当前位置:网站首页>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 !
边栏推荐
- The implementation method pathlisttomap can convert the input pathlist into a map type with hierarchical structure
- 医院综合布线
- How to synchronize MySQL database when easycvr platform is upgraded to the latest version v2.5.0?
- Solve the problem that the script tag is written in front of the element node and cannot get the element node
- 中小型医院基础网络解决方案
- Rip --- routing information protocol
- 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?
- Hcip seventh day notes
- Cmake Getting Started tutorial
- Arm architecture and programming 7 -- exceptions and interrupts (based on Baiwen arm architecture and programming tutorial video)
猜你喜欢

Excel simple macro

医院综合布线

医院无线网络系统设计

Draw a two coordinate diagram with MATLAB (the simplest in the whole network)

The difference between.Split (",", -1) and.Split (",")

20220723 record an unexplained shutdown of SAP Oracle monitoring service

Jenkins multitask concurrent construction

選址與路徑規劃問題(Lingo,Matlab實現)

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

20220723 记录一次SAP Oracle 监听服务莫名停掉的问题
随机推荐
Detailed comparison between graphic array and linked list, performance test
Sword finger offer II 031. Least recently used cache
Thread pool interview
Digicert code signing certificate
Chapter 9.2 program control of MATLAB
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?
View Binding 混淆问题。我两天都在研究混淆。
ASP. Net core write a cache attribute tool
php7 垃圾回收机制详解
20220723 record an unexplained shutdown of SAP Oracle monitoring service
[pumpkin Book ml] (task3) decision tree (updating)
文心大模型扬起新“帆”,产业应用大潮已至
[bdsec CTF 2022] partial WP
MySQL Basics (operators, sorting and paging, multi table queries, functions)
Hcip seventh day notes
Wenxin big model raises a new "sail", and the tide of industrial application has arrived
Is Huatai Securities safe to open an account? How to handle it
Spark partition operators partitionby, coalesce, repartition
解决script标签写在元素节点前面无法获取元素节点的问题
Database security and data integrity