【发布时间】:2016-05-21 00:15:23
【问题描述】:
我需要帮助来弄清楚为什么我在尝试运行我的机器代码时会在运行时崩溃。代码在“3”和“result = %li”之间崩溃。
注意:假设所有代码都经过错误检查。为了人们阅读本文,我删除了错误检查代码。
机器规格:
Windows 10 Home 64-bit
Intel(R) Core(TM) i7-4712MQ
我正在运行的代码:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main(int argc, char** argv) {
printf("Loading code\n");
LPVOID m = VirtualAlloc(NULL, 16, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
printf("1\n");
unsigned char code[] = {
//return x+2;
0x55, //push %rbp
0xe5, 0x89, 0x48, //mov %rsp,%rbp
0xc8, 0x89, //movl %ecx,%eax
0x02, 0xc0, 0x83, //add $0x2,%eax
0xc9, //leaveq
0xc3, //retq
0x90 //nop
};
memcpy(m, code, sizeof(code));
printf("2\n");
PDWORD trash;
VirtualProtect(m, 16, PAGE_EXECUTE_READ, trash);
printf("3\n");
long int (*addTwo)(long int) = m;
long int answer = addTwo(2);
printf("result = %li\n", answer);
VirtualFree(m, 0, MEM_RELEASE);
return 0;
}
【问题讨论】:
-
检查
VirtualProtect的返回值。成功了吗? (您还应该检查来自VirtualAlloc的返回值,但我认为这有效,否则memcpy会崩溃。)如果VirtualProtect成功,那么最好的办法是在汇编模式下启动调试器,并且在addTwo的声明处放一个断点。 -
为了这里的人,我删除了所有的检查代码。 @user3386109 Windows 有本机调试器还是我应该安装 gdb?
-
为了便于阅读和理解:遵循公理:每行只有一个语句,每个语句(最多)一个变量声明。。注意 'unsigned char code[]` 将数据放在 .data 部分而不是 .text 部分中,并且 .data 部分中的项目不可执行
-
typedef 将
long重新定义为(*)(long)。可能不是你想要的。 -
代码似乎没有考虑
Endianness的影响
标签: c windows runtime machine-code