我有以下代码
intptr_t location = (intptr_t)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtReadFile");
printf("addr-> %p\n", location);
我得到以下输出:
0x00007FF9DE1FC120
我使用 x64dbg/IDA 来查看“0x00007FF9DE1FC120”中的操作码
00007FF9DE1FC120 | 4C:8BD1                  | mov r10,rcx                             |
00007FF9DE1FC123 | B8 06000000              | mov eax,6                               |
00007FF9DE1FC128 | F60425 0803FE7F 01       | test byte ptr ds:[7FFE0308],1           |
00007FF9DE1FC130 | 75 03                    | jne ntdll.7FF9DE1FC135                  |
00007FF9DE1FC132 | 0F05                     | syscall                                 |
00007FF9DE1FC134 | C3                       | ret                                     |
00007FF9DE1FC135 | CD 2E                    | int 2E                                  |
00007FF9DE1FC137 | C3                       | ret                                     |
我在打印位于 0x00007FF9DE1FC120 的 20 个字节时遇到问题。
    for (int i = 0; i < 10; i++)
    {
        printf("|%x| ", (char)((location)+i));
    }
    printf("\n");
输出:
|20| |21| |22| |23| |24| |25| |26| |27| |28| |29|
我期待得到这样的东西
|4C| |8B| |D1| |B8| |06| |00| |00| |00| |F6| |04|
我很乐意得到您的帮助,谢谢
location是整数类型intptr_t location。您正在将该整数截断为char并打印该整数值,在这种情况下打印指针值的低字节。
您需要转换location回指针。要访问单个字节(当值提升为更宽int或时使用零扩展名unsigned),请使用const unsigned char *. C/C++ 严格别名规则允许通过 读取任何对象的对象表示unsigned char*,作为一个特殊的例外。  例如,这不是严格安全的const uint32_t*。
printf("|%x| ", ((const unsigned char*)location)[i] );
或者
const unsigned char *charloc = (const unsigned char*)location;
printf("|%x| ", charloc[i]);
传递给 printf 隐式转换为int通过默认整数提升1。%hhx如果需要,您可以使用告诉 printf 仅打印该unsigned charint的低位。
在 C 中,您可以使用const unsigned char *charloc = (void*)location;. 在 C++11 中,您可以使用
auto charloc = static_cast<const unsigned char*>(location);. 在 C 中,autois just int,而在 C++void*中不会自由转换为其他指针类型。因此,如果您想编写同时有效的 C 和 C++ 代码,请避免这些。
脚注 1:
%x被指定为服用unsigned int,但有没有未定义的行为,因为标准允许signed和unsigned相同的整数类型的版本是兼容的可变参数/ unprototyped ARG传递,只要值在这两种类型表示的。C17 § 6.5.2.2 6 对于 C,大概是 ISO C++ 中用于可变参数函数的类似语言。(unsigned char确保这一点,signed char可能会提升为负值int。)
https://godbolt.org/z/Tevc48显示 GCC 和 clang 即使使用 也不会警告它-Wall -Wextra -Wpedantic,即使您使用(int)charloc[i]明确地使其int,而不仅仅是促销结果。
它还显示了编译器使用movzx esi, byte ptr[rbx]加载,像我们想要的那样从内存中加载一个零扩展字节,作为 printf 的参数。从您的版本中编译器生成的 asm 不会进行任何加载,因此您可能已经发现没有得到您想要的东西。(鉴于标签,我假设您比 C 更了解汇编语言?)