c++ - 从 C++ 调用 putchar 地址

标签 c++ assembly

previous question 中,我问是否可以在内存中编写和执行汇编命令。我得到了一些很好的回应,经过更多的研究,我想出了如何去做。现在我可以做到了,但我很难弄清楚要写入内存的内容(以及如何正确执行)。我知道一些汇编以及助记符如何转换为操作码,但我不知道如何正确使用操作码。

这是我尝试开始工作的示例:

void(*test)() = NULL; //create function pointer, initialize to NULL
void* hold_address = VirtualAlloc(NULL, 5*1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE); //allocate memory, make writable/ readable/ executable
unsigned char asm_commands[] = {0x55, 0x89, 0xE5, 0x83, 0xEC, 0x18, 0xC7, 0x04, 0x24, 0x41, 0xE8, 0x1E, 0xB3, 0x01, 0x00, 0xC9, 0xC3}; //create array of assembly commands, hex values
memcpy(hold_address, asm_commands, sizeof(asm_commands)[0]*10); //copy the array into the reserved memory
test = (void(*)())hold_address; //set the function pointer to start of the allocated memory
test(); //call the function

只需将 0xC3 放入 asm_commands 数组就可以了(而且函数会返回),但这很无聊。我现在拥有的一系列操作码(和地址)应该打印出字符“A”(大写字母 a)。我通过调试调用 printf("A") 并在内存中找到调用的简单程序获得了操作码和地址。现在,程序返回 0xC00000096 错误,“特权命令”。我认为错误源于试图直接调用系统 putchar 地址,系统不喜欢这样。我还认为我可以通过为我的程序提供 Ring 0 访问权限来绕过它,但除了很多潜在问题之外,我几乎不知道这会带来什么。

那么有没有什么方法可以在不需要更高权限的情况下调用 printf() 函数(在汇编操作码中)?

我使用的是 Windows 7,64 位,Code::Blocks 10.05(GNU GCC 编译器)。

这是调试过的 printf() 调用的屏幕截图(在 OllyDebug 中):

最佳答案

unsigned char asm_commands[] = {0x55, 0x89E5…

哇哦,等一下,就停在那里。 0x89E5 不是 unsigned char 的有效值,您的编译器可能会提示这一点。 (如果没有,请检查您的设置;您可能已经禁用了一些非常重要的警告。)

您需要将此初始化程序中的代码拆分为单独的字节,例如

{0x55, 0x89, 0xE5, …

关于c++ - 从 C++ 调用 putchar 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28336948/

相关文章:

c++ - 在 VC++ 中的 1 个原子操作内将值设置为 POD(没有构造函数/析构函数)

assembly - X86 切换到 32 位保护模式

assembly - ARM-Assembly : Arithmetic Shift/Logical Shift

assembly - ASM:MASM,NASM,FASM?

assembly - 在x86程序集中打印寄存器值的简单方法

c++ - 做OOP状态机设计时如何避免单例?

c++ - 重载 new 和 delete C++ 以跟踪内存分配

c++ - 如何使用 gdb 查看 C++ 类在内存中的布局?

c - 不使用 ebp 实现堆栈回溯

c++ - 从 cpp 中的 curl 检索响应文本