我写了一个连接到进程的dll应用程序。它有效,但它只显示第一个字母 我想得到整个字符串。字符串可以从2个字母到32个字母不等。
//READING MEMORY
HANDLE ExeBaseAddress = GetModuleHandleA(0);
char uNameAddr = *(char*)((char*)ExeBaseAddress + 0x34F01C);
printf("%c \n", uNameAddr);
我也想了解这些部分:
*(char*)((char*) //<-- what this is for.
如果使用多级指针可以使用它:
char multipoint = *(char*)((char*)ExeBaseAddress + 0x34F01C + 0x123 + 0x321 + 0x20);
更新
我猜这里有些不对劲:
if(uNameAddr == "omnicient")
cout << "YOU ARE OMNI" << endl;
我使用的是用户名omnicient
,但没有使用YOU ARE OMNI
。我想我的比较是错的?
答案 0 :(得分:2)
char uNameAddr是一个字符,你需要一个字符列表(或char *)
试试这个:
char* name= (char*)((char*)ExeBaseAddress + 0x34F01C);
printf("%s \n", name);
*(char*)((char*)
是什么意思?
(char*)ExeBaseAddress
将ExeBaseAddress视为指向char
((char*)ExeBaseAddress + 0x34F01C)
表示将0x34F01C添加到上面的指针,将其偏移0x34F01C字符
(char*)((char*)ExeBaseAddress + 0x34F01C)
表示将此新地址视为指向某些字符的指针
*(char*)((char*)ExeBaseAddress + 0x34F01C)
获取该位置第一个字符的内容
char uNameAddr = *(char*)((char*)ExeBaseAddress + 0x34F01C);
表示将该字符放入名为uNameAddr的char大小的变量中。
所以基本上你有一个指针,你偏移它,然后拿出第一个字符并打印出来。
在示例中,我给出了如何不接受firat字符,并将其作为指针变量。
然后我在printf中使用了%s来打印出所有按名称填充的字符。
答案 1 :(得分:2)
%c
显示char
s(单个字符),%s
显示以NULL结尾的char*
s(字符串):
HANDLE ExeBaseAddress = GetModuleHandleA(0);
char *uNameAddr = (char*) ExeBaseAddress + 0x34F01C;
printf("%s \n", uNameAddr);
请注意,我还整理了指针转换,但重要的是我摆脱了最后的解除引用(前面是*
)并将其分配给char*
(指针)而不是char
。
如果你的字符串不是以NULL结尾(不太可能),你需要使用%.*s
并传递字符串的长度。
至于问题的第二部分:
*(char*)((char*) ExeBaseAddress + 0x34F01C)
让我们把它分解。在括号内(因此首先要评估的是):
(char *) ExeBaseAddress + 0x34F01C
那是一个C演员(将HANDLE
投射到char*
)然后添加。换句话说,它说“把这个东西看作是指向某个内存的指针,然后向前看0x34F01C字节的内存”(char
总是1个字节)。它现在是指向内存中新位置的指针。
然后我们离开括号并再次投射到char*
......不必要。可能是:
*((char*) ExeBaseAddress + 0x34F01C)
最后我们取消引用(前面的*
),其中写着“现在告诉我你指的内存是多少”。但是在这种情况下你不需要它,因为你想要整个字符串,而不仅仅是第一个字母(在printf
内),它沿着你发送的内存循环打印每个字符,直到它找到{{1} },又名0
又名\0
)。