用C语言在Unicorn emulator中设置堆栈和堆
我正在尝试使用Unicorn emulator学习x86汇编,在我尝试使用push或pop之前一切都很顺利,我在web上搜索了教程,但我找不到任何有用的关于堆栈的内容。当我尝试使用push或pop“uc_emu_start()失败,返回错误7:无效内存写入(uc_ERR_write_UNMAPPED)”时,会出现此错误用C语言在Unicorn emulator中设置堆栈和堆,c,assembly,x86,C,Assembly,X86,我正在尝试使用Unicorn emulator学习x86汇编,在我尝试使用push或pop之前一切都很顺利,我在web上搜索了教程,但我找不到任何有用的关于堆栈的内容。当我尝试使用push或pop“uc_emu_start()失败,返回错误7:无效内存写入(uc_ERR_write_UNMAPPED)”时,会出现此错误 #包括 //要仿真的代码 #定义X86_代码32“\xB9\x05\x00\x00\x00\x00\x51\x5A” //模拟开始的内存地址 #定义地址0x600000 //#定
#包括
//要仿真的代码
#定义X86_代码32“\xB9\x05\x00\x00\x00\x00\x51\x5A”
//模拟开始的内存地址
#定义地址0x600000
//#定义地址\u STC 0x100000
#定义地址\u STC 0x6000000
内部主(内部argc、字符**argv、字符**envp)
{
uc_引擎*uc;
//uc_引擎*uc0;
uc_err err;
uc_err err0;
//int r_ecx=0x1234;//ecx寄存器
int r_ecx;//ecx寄存器
int r_edx;//edx寄存器
国际反倾销税;
int r_esp0=0x7FFFFF;
printf(“模拟i386代码\n”);
//在X86-32位模式下初始化仿真器
err=uc_打开(uc_拱形_X86、uc_模式_32和uc);
如果(错误!=UC\u错误\u正常){
printf(“在uc_open()上失败,返回错误:%u\n”,错误);
返回-1;
}
//映射此模拟的2MB内存
uc_mem_地图(uc,地址,1*1024*1024,uc_保护全部);
//uc成员地图(uc,地址STC,2*1024*1024,uc保护全部);
printf(“Mike\n”);
//将要仿真的机器代码写入内存
if(uc_mem_write(uc,地址,X86_代码32,sizeof(X86_代码32)-1)){
printf(“未能将仿真代码写入内存,退出!\n”);
返回-1;
}
printf(“Mike 0\n”);
//初始化机器寄存器
uc_reg_写入(uc、uc_X86_reg_EBP和r_esp0+512);
uc_reg_写入(uc、uc_X86_reg_ESP和r_esp0+512);
printf(“Mike 01\n”);
//在无限时间和无限指令中模拟代码
err=uc\u emu\u start(uc,地址,地址+sizeof(X86\u代码32)-1,0,0);
如果(错误){
printf(“uc\u emu\u start()失败,返回错误%u:%s\n”,
呃,uc_strerror(呃),;
uc_reg_read(uc、uc_X86_reg_RSP和r_esp0);
printf(“esp0 0x%x\n”,r\u esp0);
}
//现在打印出一些寄存器
printf(“仿真完成。下面是CPU上下文\n”);
uc_reg_读取(uc、uc_X86_reg_ECX和r_ECX);
uc_reg_读取(uc、uc_X86_reg_EBP和r_edx);
uc_reg_read(uc、uc_X86_reg_ESP和r_ESP);
printf(“>>>EX=0x%x\n”,r\u ecx);
printf(“>>>EDX=0x%x\n”,r\u EDX);
printf(“>>>ESP=0x%x\n”,r\u ESP);
uc_close(uc);
返回0;
}
ESP设置为0x600,但内存从0x400000开始映射。ESP设置为0x600,但内存从0x400000开始映射。unicorn-标记与您的“unicorn”无关。unicorn
-标记与您的“unicorn”无关这听起来很愚蠢,但是我应该把内存移到哪里,或者把ESP移到哪里?是否应该将其移动到映射内存?这完全取决于您计划在模拟器中运行的代码。现在你只使用400000-400006,所以你可以把堆栈放在任何地方。尝试将ESP设置为410000。如果要开始使用严肃的代码,可能需要代码和数据的单独映射,以便代码可以是只读的,数据可以是不可执行的。那么,数据和堆栈可能位于0x600000-0x7FFFFF.btw,我是使用“uc_reg_write(uc,uc_X86_reg_ESP,&r_esp0+512)”来设置堆栈,还是用另一种方式设置堆栈?您做了这么多更改!我建议您回到原来的程序,只需更改uc_reg_write(uc,uc_X86_reg_RSP,1024+512)代码>至uc_reg_写入(uc,uc_X86_reg_RSP,0x410000)代码>这听起来很愚蠢,但是我应该把内存移到哪里,或者把ESP移到哪里?是否应该将其移动到映射内存?这完全取决于您计划在模拟器中运行的代码。现在你只使用400000-400006,所以你可以把堆栈放在任何地方。尝试将ESP设置为410000。如果要开始使用严肃的代码,可能需要代码和数据的单独映射,以便代码可以是只读的,数据可以是不可执行的。那么,数据和堆栈可能位于0x600000-0x7FFFFF.btw,我是使用“uc_reg_write(uc,uc_X86_reg_ESP,&r_esp0+512)”来设置堆栈,还是用另一种方式设置堆栈?您做了这么多更改!我建议您回到原来的程序,只需更改uc_reg_write(uc,uc_X86_reg_RSP,1024+512)代码>至uc_reg_写入(uc,uc_X86_reg_RSP,0x410000)代码>
#include <unicorn/unicorn.h>
// code to be emulated
#define X86_CODE32 "\xB9\x05\x00\x00\x00\x51\x5A"
// memory address where emulation starts
#define ADDRESS 0x600000
//#define ADDRESS_STC 0x100000
#define ADDRESS_STC 0x6000000
int main(int argc, char **argv, char **envp)
{
uc_engine *uc;
//uc_engine *uc0;
uc_err err;
uc_err err0;
//int r_ecx = 0x1234; // ECX register
int r_ecx; // ECX register
int r_edx; // EDX register
int r_esp;
int r_esp0 = 0x7FFFFF;
printf("Emulate i386 code\n");
// Initialize emulator in X86-32bit mode
err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc);
if (err != UC_ERR_OK) {
printf("Failed on uc_open() with error returned: %u\n", err);
return -1;
}
// map 2MB memory for this emulation
uc_mem_map(uc, ADDRESS, 1 * 1024 * 1024, UC_PROT_ALL);
//uc_mem_map(uc, ADDRESS_STC, 2 * 1024 * 1024, UC_PROT_ALL);
printf("Mike \n");
// write machine code to be emulated to memory
if (uc_mem_write(uc, ADDRESS, X86_CODE32, sizeof(X86_CODE32) - 1)) {
printf("Failed to write emulation code to memory, quit!\n");
return -1;
}
printf("Mike 0\n");
// initialize machine registers
uc_reg_write(uc,UC_X86_REG_EBP, &r_esp0+512);
uc_reg_write(uc,UC_X86_REG_ESP, &r_esp0+512);
printf("Mike 01\n");
// emulate code in infinite time & unlimited instructions
err=uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32) - 1, 0, 0);
if (err) {
printf("Failed on uc_emu_start() with error returned %u: %s\n",
err, uc_strerror(err));
uc_reg_read(uc,UC_X86_REG_RSP,&r_esp0);
printf("esp0 0x%x\n",r_esp0);
}
// now print out some registers
printf("Emulation done. Below is the CPU context\n");
uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx);
uc_reg_read(uc, UC_X86_REG_EBP, &r_edx);
uc_reg_read(uc, UC_X86_REG_ESP, &r_esp);
printf(">>> EX = 0x%x\n", r_ecx);
printf(">>> EDX = 0x%x\n", r_edx);
printf(">>> ESP = 0x%x\n", r_esp);
uc_close(uc);
return 0;
}