C/C++游戏逆向

C基础

结构体

定义

  • 结构体类型声明 注意最后一定要加分号
  • 如果结构体变量已经定义,可以对每个成员单独赋值,如s.num = 1003;
struct student
{
	int num;
	char name[20];
	char sex;
	int age;
	float score;
	char addr[30];
}; // 结构体类型声明 注意最后一定要加分号

赋值

struct student s = {1, "小红", 'F', 19, 99.0, "BEIJING"};

输出

  • 结构体输出不能直接输出需要每一个字段单独输出
printf("%d %s %c %d %f %s\n", s.num, s.name, s.sex, s.age, s.score, s.addr);

结构体数组

struct student sarr[3]; // 定义一个结构体数组
for (int i = 0; i < 3; i++)
{
	scanf("%d %s %c %d %f %s", &sarr[i].num, sarr[i].name, &sarr[i].sex, &sarr[i].age, &sarr[i].score, sarr[i].addr);
}
for (int i = 0; i < 3; i++)
{
	printf("%d %s %c %d %f %s\n", sarr[i].num, sarr[i].name, sarr[i].sex, sarr[i].age, sarr[i].score, sarr[i].addr);
}

完整代码:

#include <stdio.h>


struct student
{
	int num;
	char name[20];
	char sex;
	int age;
	float score;
	char addr[30];
}; // 结构体类型声明 注意最后一定要加分号

int main()
{
	struct student s = {1, "小红", 'F', 19, 99.0, "BEIJING"};
	printf("%d %s %c %d %f %s\n", s.num, s.name, s.sex, s.age, s.score, s.addr);
	printf("------------------------------------------------------------------\n");
	int num_of_values_read = scanf("%d %s %c %d %f %s", &s.num, s.name, &s.sex, &s.age, &s.score, s.addr);
	printf("num_of_values_read:%d\n", num_of_values_read);
	if (num_of_values_read == 6) printf("Input successful!\n");
	else printf("Input error! Please enter valid data.\n");
	printf("%d %s %c %d %f %s\n", s.num, s.name, s.sex, s.age, s.score, s.addr);
	
	
	struct student sarr[3]; // 定义一个结构体数组
	for (int i = 0; i < 3; i++)
	{
		scanf("%d %s %c %d %f %s", &sarr[i].num, sarr[i].name, &sarr[i].sex, &sarr[i].age, &sarr[i].score, sarr[i].addr);
	}
	for (int i = 0; i < 3; i++)
	{
		printf("%d %s %c %d %f %s\n", sarr[i].num, sarr[i].name, sarr[i].sex, sarr[i].age, sarr[i].score, sarr[i].addr);
	}
}

结构体对齐

  • 结构体的大小必须是其最大成员的整数倍
  • 结构体对齐是为了CPU能够更高效的去取数据
struct MyStruct1
{
	int a;
	char b;
	short c;
};
  • charshort加起来占用3个字节,不够4个,所以charshort一起占用四个字节,这个结构体一共占用8个字节
struct MyStruct2
{
	int a; // 4
	char c[20]; // 20
	char b; // 4
};

  • 上面结构体一共占用28个字节

结构体指针

一个结构体变量的指针就是该变量所占据的内存段的起始地址

  • 指针访问结构体变量用的是->(推荐),也可以使用(*p).属性的方式,但不推荐
struct MyStruct1
{
	int a;
	char b;
	short c;
};
struct MyStruct1* p;
printf("p:%zu\n", sizeof(p)); // 所有指针大小都是4个字节(32位操作系统)
p = &s1;
printf("%d %c %hd\n", s1.a, s1.b, s1.c);
printf("%d %c %hd\n", (*p).a, (*p).b, (*p).c); // 第一种访问方式
printf("%d %c %hd\n", p->a, p->b, p->c); // 第二种访问方式

结构体指针数组

struct MyStruct1 sarr[3] = {1, 'a', 1, 2, 'b', 2 , 3, 'c', 3 };
p = sarr;
printf("%d %c %hd\n", p->a, p->b, p->c);
printf("%d %c %hd\n", sarr[0].a, sarr->b, sarr->c);
  • p = sarr;相当于将sarr的首地址赋值给p,所以打印结果是:1 a 1
  • 上面两句打印结果相同
    typedef
  • 作用:起别名
typedef struct MyStruct2
{
	int a;
	char c[20];
	char b;
}stu, *pstu;

上面代码相当于typedef struct MyStruct2 stu; typedef struct MyStruct2* pstu;

初级

%p、size_t、%zd、%llu、sizeof

  • %p用于输出地址,HWND类型的也可以使用%p输出
  • size_t:C语言源代码:typedef unsigned __int64 size_t;
  • sizeof 返回值是 size_t类型,打印的时候不能使用%d,应该使用%zu
  • 在这里插入图片描述

修改窗口标题

#include <stdio.h>
#include <Windows.h>
#include <locale.h>

int main()
{
	
	HWND hWnd = FindWindowA(NULL, "微信"); // 获取窗口句柄
	if (NULL == hWnd)
	{
		printf("错误代码:%d", GetLastError());
		return 0;
	}
	printf("窗口句柄:0x%p\n", hWnd);
	printf("初始化本地环境:%s\n", setlocale(NULL, ""));
	WCHAR lpString[255];
	printf("请输入需要设置的窗口标题:");
	wscanf_s(L"%254ls", lpString, (unsigned)_countof(lpString));
	wprintf(L"新窗口标题:%ls\n", lpString);
	if (SetWindowText(hWnd, lpString))
	{
		printf("修改成功!\n");
	}
}
  • FindWindowA函数用于获取窗口句柄,还可以使用FindWindow和FindWindowW,FindWindowFindWindowW是一样的,需要传入宽字符。
  • SetWindowText函数一共两个参数,第一个参数是窗口句柄,第二个参数是需要设置的新的窗口名字,是宽字符。

在C++中使用宽字符

printf("初始化本地环境:%s\n", setlocale(NULL, ""));
WCHAR lpString[255];
printf("请输入需要设置的窗口标题:");
wscanf_s(L"%254ls", lpString, (unsigned)_countof(lpString));
wprintf(L"新窗口标题:%ls\n", lpString);

使用宽字符需要先初始化本地环境使用setlocale函数,包含在locale.h头文件中,然后需要使用wscanf_s函数来接收输入字符串,使用wprintf函数进行打印。

获取进程PID

#include <Windows.h>
#include <stdio.h>

/*
获取进程PID TID
GetWindowThreadProcessId
hWnd           窗口句柄
lpdwProcessId  一个DWORD类型的指针
*/

int main()
{
	HWND hWnd = FindWindowA(NULL, "微信");
	if (NULL == hWnd)
	{
		return 0;
	}
	printf("获取到的窗口句柄:0x%p\n", hWnd);
	DWORD dwProcessId;
	// GetWindowThreadProcessId((HWND)0x3F05E2, &dwProcessId); // 这样直接写窗口句柄也是可以的 不过需要强制类型转换
	GetWindowThreadProcessId(hWnd, &dwProcessId);
	printf("获取到的进程PID:0x%lX", dwProcessId);
}
  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值