当前位置:网站首页>Build a CPU Simulator
Build a CPU Simulator
2022-07-24 01:59:00 【Xiuchuan dizang.】
One 、 summary
This chapter introduces windows In the environment unicorn The framework and capstone Use of framework .
Two 、 Tools
Visual stdio 2019
Cmake
Git
3、 ... and 、 Build steps
1、clone unicorn and capstone Source code of framework .( Be careful clone The branch of is the latest version , No master)
git clone https://github.com/unicorn-engine/unicorn.git
git clone https://github.com/capstone-engine/capstone.git
2、 compile unicorn
(1) Use git bash perhaps cmd Get into unicorn Catalog , Execute the following commands
mkdir build
cd build
cmake .. -G "Visual Studio 16 2019" -A "x64" -DCMAKE_BUILD_TYPE=Release(2) And then build A... Will be generated in the directory unicorn.sln file , Use visual stdio 2019 open , Compile output . stay build The directory will generate unicorn.lib, stay build/debug Many files will be generated under the directory , It only needs unicorn.dll that will do .


3、 compile capstone
(1) Use visual stdio 2019 open capstone/msvc In the catalog capstone.sln file , After compiling, in capstone\msvc\x64\Debug The directory will generate capstone.dll and capstone.lib file .

4、 Create simulator project
Use visual stdio 2019 Create a new project , Then import the file generated in the above two steps , Then put the above frame
capstone and unicorn The header file ( stay include Under the table of contents ) Put it into the project root directory .

5、 Implementation code
Here's the simulation x86 framework 64 Bit program code fragment , among test_00007FF6B9541000.bin yes .text Memory of segment dump file ,test_00000039AB52A000.bin by .stack Segment memory dump,test_00007FF6B9549000.bin by .rdata Segment memory dump,test_00007FF6B954C000.bin by .data Segment memory dump,test_00007FF6B9531000.bin by .textbss Segment memory dump.
csh g_x64_cs_handle = NULL;
cs_insn* g_x64_cs_insn = NULL;
size_t g_x64_cs_count = 0; // how many instruction that this capstone API disassembly successfully
cs_err g_x64_cs_err = CS_ERR_OK;
uc_engine* g_x64_uc = NULL;
uc_err g_x64_uc_err = UC_ERR_OK; // error number that unicorn emulate instruction
DWORD64 g_x64_instruction_count = 0;
REG_X86 g_x64_reg = { 0 }; // init register
//#define CODE "\x55\x48\x8b\x05\xb8\x13\x00\x00"
VOID x64_init_registers()
{
g_x64_reg.reg.r_rax = 0x00007FF6B9541230;
g_x64_reg.reg.r_rcx = 0x00000039AB77F000;
g_x64_reg.reg.r_rdx = 0x00007FF6B9541230;
g_x64_reg.reg.r_rbx = 0x0000000000000000;
g_x64_reg.reg.r_rsp = 0x00000039AB52FDB8;
g_x64_reg.reg.r_rbp = 0x0000000000000000l;
g_x64_reg.reg.r_rsi = 0x0000000000000000;
g_x64_reg.reg.r_rdi = 0x0000000000000000;
g_x64_reg.reg.r_rip = 0x00007FF6B9542330;
g_x64_reg.reg.r_rflag = 0x0000000000000246;
g_x64_reg.reg.r_r8 = 0x00000039AB77F000;
g_x64_reg.reg.r_r9 = 0x00007FF6B9541230;
g_x64_reg.reg.r_r10 = 0x00007FFFBD807C90;
g_x64_reg.reg.r_r11 = 0x0000000000000000l;
g_x64_reg.reg.r_r12 = 0x0000000000000000l;
g_x64_reg.reg.r_r13 = 0x0000000000000000l;
g_x64_reg.reg.r_r14 = 0x0000000000000000l;
g_x64_reg.reg.r_r15 = 0x0000000000000000l;
}
x64_FileInformation fileinfo[] =
{
// BaseAddress FileSize Path allocate buffer address
(PVOID)0x00007FF6B9541000 , 0x8000 , L".\\x64_binary\\test_00007FF6B9541000.bin" , NULL , //.text
(PVOID)0x00000039AB52A000 , 0x6000 , L".\\x64_binary\\test_00000039AB52A000.bin" , NULL , //.stack
(PVOID)0x00007FF6B9549000 , 0x3000 , L".\\x64_binary\\test_00007FF6B9549000.bin" , NULL , //.rdata
(PVOID)0x00007FF6B954C000 , 0x1000 , L".\\x64_binary\\test_00007FF6B954C000.bin" , NULL , //.data
(PVOID)0x00007FF6B9531000 , 0x10000 , L".\\x64_binary\\test_00007FF6B9531000.bin" , NULL , //.textbss
};
VOID x64_emulate()
{
g_x64_cs_err = cs_open(CS_ARCH_X86, CS_MODE_64, &g_x64_cs_handle);
g_x64_uc_err = uc_open(UC_ARCH_X86, UC_MODE_64, &g_x64_uc);
if (g_x64_cs_err || g_x64_uc_err)
{
printf("ERROR: Failed to initialize engine!\n");
return;
}
cs_option(g_x64_cs_handle, CS_OPT_DETAIL, CS_OPT_ON);
for (ULONG i = 0; i < sizeof(fileinfo) / sizeof(fileinfo[0]); i++)
{
FILE* pFile = NULL;
fileinfo[i].buffer = (PVOID)malloc(fileinfo[i].FileSize);
if (!fileinfo[i].buffer)
{
printf("Allocate mem fail!\n");
return;
}
pFile = _wfopen(fileinfo[i].FileName, L"rb");
if (!pFile)
{
printf("open file error code : <%d>\n", GetLastError());
return;
}
fread(fileinfo[i].buffer, fileinfo[i].FileSize, 1, pFile);
if (pFile)
fclose(pFile);
g_x64_uc_err = uc_mem_map(g_x64_uc, (DWORD64)fileinfo[i].BaseAddress, fileinfo[i].FileSize, UC_PROT_ALL);
if (g_x64_uc_err)
{
printf("uc mem map error!Error Code:<%d>\n", g_x64_uc_err);
return;
}
g_x64_uc_err = uc_mem_write(g_x64_uc, (DWORD64)fileinfo[i].BaseAddress, fileinfo[i].buffer, fileinfo[i].FileSize);
if (g_x64_uc_err)
{
printf("uc mem write error!Error Code:<%d>\n", g_x64_uc_err);
return;
}
}
x64_init_registers();
x64_write_uc_registers();
BYTE Code[32] = { 0 };
do
{
uc_mem_read(g_x64_uc, g_x64_reg.reg.r_rip, Code, sizeof(Code));
g_x64_cs_count = cs_disasm(g_x64_cs_handle, Code, sizeof(Code), g_x64_reg.reg.r_rip, 1, &g_x64_cs_insn);
if (!g_x64_cs_count)
break;
g_x64_uc_err = uc_emu_start(g_x64_uc, g_x64_reg.reg.r_rip, 0xffffffffffffffff, 0, 1);
x64_read_uc_registers();
x64_print_uc_registers();
x64_print_uc_stack(g_x64_reg.reg.r_rsp);
cs_free(g_x64_cs_insn, 1);
if (g_x64_uc_err)
{
printf("uc_emu_start error!Error Code:<%d>\n", g_x64_uc_err);
break;
}
g_x64_instruction_count++;
} while (g_x64_cs_count);
cs_close(&g_x64_cs_handle);
uc_close(g_x64_uc);
}
VOID x64_read_uc_registers()
{
uc_reg_read(g_x64_uc, UC_X86_REG_RAX, &g_x64_reg.reg.r_rax);
uc_reg_read(g_x64_uc, UC_X86_REG_RCX, &g_x64_reg.reg.r_rcx);
uc_reg_read(g_x64_uc, UC_X86_REG_RDX, &g_x64_reg.reg.r_rdx);
uc_reg_read(g_x64_uc, UC_X86_REG_RBX, &g_x64_reg.reg.r_rbx);
uc_reg_read(g_x64_uc, UC_X86_REG_RSP, &g_x64_reg.reg.r_rsp);
uc_reg_read(g_x64_uc, UC_X86_REG_RBP, &g_x64_reg.reg.r_rbp);
uc_reg_read(g_x64_uc, UC_X86_REG_RSI, &g_x64_reg.reg.r_rsi);
uc_reg_read(g_x64_uc, UC_X86_REG_RDI, &g_x64_reg.reg.r_rdi);
uc_reg_read(g_x64_uc, UC_X86_REG_RIP, &g_x64_reg.reg.r_rip);
uc_reg_read(g_x64_uc, UC_X86_REG_RFLAGS, &g_x64_reg.reg.r_rflag);
uc_reg_read(g_x64_uc, UC_X86_REG_R8, &g_x64_reg.reg.r_r8);
uc_reg_read(g_x64_uc, UC_X86_REG_R9, &g_x64_reg.reg.r_r9);
uc_reg_read(g_x64_uc, UC_X86_REG_R10, &g_x64_reg.reg.r_r10);
uc_reg_read(g_x64_uc, UC_X86_REG_R11, &g_x64_reg.reg.r_r11);
uc_reg_read(g_x64_uc, UC_X86_REG_R12, &g_x64_reg.reg.r_r12);
uc_reg_read(g_x64_uc, UC_X86_REG_R13, &g_x64_reg.reg.r_r13);
uc_reg_read(g_x64_uc, UC_X86_REG_R14, &g_x64_reg.reg.r_r14);
uc_reg_read(g_x64_uc, UC_X86_REG_R15, &g_x64_reg.reg.r_r15);
}
VOID x64_write_uc_registers()
{
uc_reg_write(g_x64_uc, UC_X86_REG_RAX, &g_x64_reg.reg.r_rax);
uc_reg_write(g_x64_uc, UC_X86_REG_RCX, &g_x64_reg.reg.r_rcx);
uc_reg_write(g_x64_uc, UC_X86_REG_RDX, &g_x64_reg.reg.r_rdx);
uc_reg_write(g_x64_uc, UC_X86_REG_RBX, &g_x64_reg.reg.r_rbx);
uc_reg_write(g_x64_uc, UC_X86_REG_RSP, &g_x64_reg.reg.r_rsp);
uc_reg_write(g_x64_uc, UC_X86_REG_RBP, &g_x64_reg.reg.r_rbp);
uc_reg_write(g_x64_uc, UC_X86_REG_RSI, &g_x64_reg.reg.r_rsi);
uc_reg_write(g_x64_uc, UC_X86_REG_RDI, &g_x64_reg.reg.r_rdi);
uc_reg_write(g_x64_uc, UC_X86_REG_RIP, &g_x64_reg.reg.r_rip);
uc_reg_write(g_x64_uc, UC_X86_REG_RFLAGS, &g_x64_reg.reg.r_rflag);
uc_reg_write(g_x64_uc, UC_X86_REG_R8, &g_x64_reg.reg.r_r8);
uc_reg_write(g_x64_uc, UC_X86_REG_R9, &g_x64_reg.reg.r_r9);
uc_reg_write(g_x64_uc, UC_X86_REG_R10, &g_x64_reg.reg.r_r10);
uc_reg_write(g_x64_uc, UC_X86_REG_R11, &g_x64_reg.reg.r_r11);
uc_reg_write(g_x64_uc, UC_X86_REG_R12, &g_x64_reg.reg.r_r12);
uc_reg_write(g_x64_uc, UC_X86_REG_R13, &g_x64_reg.reg.r_r13);
uc_reg_write(g_x64_uc, UC_X86_REG_R14, &g_x64_reg.reg.r_r14);
uc_reg_write(g_x64_uc, UC_X86_REG_R15, &g_x64_reg.reg.r_r15);
}
VOID x64_print_uc_registers()
{
printf("\n>--- --- --- %lld --- --- ---<\n", g_x64_instruction_count);
printf("%#16llx:\t%s\t%s\n",g_x64_cs_insn[0].address,g_x64_cs_insn[0].mnemonic,g_x64_cs_insn[0].op_str);
printf("rax=0x%16llx\n", g_x64_reg.reg.r_rax);
printf("rcx=0x%16llx\n", g_x64_reg.reg.r_rcx);
printf("rdx=0x%16llx\n", g_x64_reg.reg.r_rdx);
printf("rbx=0x%16llx\n", g_x64_reg.reg.r_rbx);
printf("rsp=0x%16llx\n", g_x64_reg.reg.r_rsp);
printf("rbp=0x%16llx\n", g_x64_reg.reg.r_rbp);
printf("rsi=0x%16llx\n", g_x64_reg.reg.r_rsi);
printf("rdi=0x%16llx\n", g_x64_reg.reg.r_rdi);
printf("rip=0x%16llx\n", g_x64_reg.reg.r_rip);
printf("rfl=0x%16llx\n", g_x64_reg.reg.r_rflag);
printf("r8 =0x%16llx\n", g_x64_reg.reg.r_r8);
printf("r9 =0x%16llx\n", g_x64_reg.reg.r_r9);
printf("r10=0x%16llx\n", g_x64_reg.reg.r_r10);
printf("r11=0x%16llx\n", g_x64_reg.reg.r_r11);
printf("r12=0x%16llx\n", g_x64_reg.reg.r_r12);
printf("r13=0x%16llx\n", g_x64_reg.reg.r_r13);
printf("r14=0x%16llx\n", g_x64_reg.reg.r_r14);
printf("r15=0x%16llx\n", g_x64_reg.reg.r_r15);
}
VOID x64_print_uc_stack(DWORD64 rsp)
{
DWORD64 val = 0;
for (ULONG i = 5; i > 0; i--)
{
uc_mem_read(g_x64_uc, (DWORD64)(rsp - i * 8), &val, sizeof(DWORD64));
printf("\t|%16llx|\n", val);
}
uc_mem_read(g_x64_uc, (DWORD64)rsp, &val, sizeof(DWORD64));
printf("===> |%16llx|\n", val);
for (ULONG i = 1; i < 5; i++)
{
uc_mem_read(g_x64_uc, (DWORD64)(rsp + i * 8), &val, sizeof(DWORD64));
printf("\t|%16llx|\n", val);
}
}
The above code simulates x86_64 Program , This cpu The simulator framework also supports arm,aarch64,mips,risc-v
risc-v 64 Wait for assembly simulation . Simulation will be given later risc-v 64 Procedure steps .
There are still many deficiencies in the learning process , I hope my friends will correct me !
边栏推荐
- Exchange 2010通配符SSL证书安装文档
- Summary of volatile interview in concurrent programming
- CANopen communication - PDO and SDO
- [重要通知]星球线上培训第三期来袭!讲解如何在QTYX上构建自己的量化策略!...
- Customer first | domestic Bi leader, smart software completes round C financing
- Structure the second operation of the actual combat battalion module
- Hospital generic cabling
- Vue3 uses keep alive to cache pages, but every time you switch the tab to enter the page, it will still enter onmounted, resulting in no caching effect. Why?
- "Guanghetong AI intelligent module sca825-w" with full AI performance accelerates the era of e-commerce live broadcast 2.0
- Hcip experiment
猜你喜欢

深入了解-微信开发者工具

小散量化炒股记|基于多任务爬虫技术, 实现A股实时行情Level1采样

Improvement of DB file sequential read caused by insert

STM32安装教程和J-link烧录驱动安装教程【第二天】

Distributed resource management and task scheduling framework yarn

20220723 record an unexplained shutdown of SAP Oracle monitoring service

Rip --- routing information protocol

Magazine feature: the metauniverse will reshape our lives, and we need to make sure it gets better

选址与路径规划问题(Lingo,Matlab实现)

Phpcms realizes product multi condition screening function
随机推荐
暑假第三周
How to use the directory classification function of the new version of easycvr (v2.5.0)?
Qt::WA_ Transparentformouseevents
Code reading methods and best practices
On the possibility and limitation of defi in the metauniverse
Rip --- routing information protocol
Install go environment under Kali
Problèmes de localisation et de planification des itinéraires (Lingo, mise en œuvre de MATLAB)
Hcip seventh day notes
J. Serval and essay (tarjan finds topological order)
Chapter 9.2 program control of MATLAB
Spark partition operators partitionby, coalesce, repartition
Vantui, axiso, FAQs and usage:
Webshell management tool and its traffic characteristics analysis
[C language operation of linked list (initialization, establishment, length calculation, addition, deletion, and output of linked list)]
jenkins多任務並發構建
hdu-7141 Ball (bitset)
xxl-job使用注意事项
Digicert code signing certificate
Exchange 2010 wildcard SSL certificate installation document