[C++] 纯文本查看 复制代码
#include <cassert>
#include <windows.h>
#include <cstdio>
#include <iostream>
#include <TlHelp32.h>
#include <vector>
#include "unicorn-2.0.1-win32/include/unicorn/unicorn.h"
#include "capstone-5.0/include/capstone/capstone.h"
using namespace std;
uc_engine* uc;
uc_err uc_error;
csh cshandle;
cs_insn* insn;
cs_err cs_error;
size_t count;
BYTE Buffer[5000000];
//jmp far 1
// UINT64 rax = 0x0000000000000004;
// UINT64 rbx = 0x00000000ff5d11cf;
// UINT64 rcx = 0x000000000019f6bc;
// UINT64 rdx = 0x0000000000c7bf47;
// UINT64 rsi = 0x0000000000bb8baa;
// UINT64 rdi = 0x0000000000bbe808;
// UINT64 rsp = 0x000000000019f630;
// UINT64 rbp = 0x000000000019f748;
// UINT64 r8 = 0x000000000000002b;
// UINT64 r9 = 0x000000007757624c;
// UINT64 r10 = 0x0000000000000000;
// UINT64 r11 = 0x0000000000000246;
// UINT64 r12 = 0x000000000024f000;
// UINT64 r13 = 0x000000000009fda0;
// UINT64 r14 = 0x000000000009ed00;
// UINT64 r15 = 0x00000000774f4770;
// UINT64 rip = 0x0000000000c5c9e8;
// UINT64 rfl = 0x0000000000000206;
//jmp far 3
// uint64_t rax = 0x0000000000000032 ;
// uint64_t rbx = 0x000000000087c678 ;
// uint64_t rcx = 0x0000000000000005 ;
// uint64_t rdx = 0x000000000019f6bc ;
// uint64_t rsi = 0x000000000019f744 ;
// uint64_t rdi = 0x0000000000c3cd0d ;
// uint64_t rip = 0x0000000000a9040b ;
// uint64_t rsp = 0x000000000019f630 ;
// uint64_t rbp = 0x0000000000acc57b ;
// uint64_t r8 = 0x000000000019f5e8 ;
// uint64_t r9 = 0x0000000000000000 ;
// uint64_t r10 = 0x00000000ffffffff ;
// uint64_t r11 = 0x0000000000000246 ;
// uint64_t r12 = 0x000000000021d000 ;
// uint64_t r13 = 0x000000000009fda0 ;
// uint64_t r14 = 0x000000000009ed00 ;
// uint64_t r15 = 0x00000000774f4770 ;
// uint64_t rfl = 0x0000000000000206 ;
//jmp far 4
uint64_t rax = 0x0019F6BC;
uint64_t rbx = 0x00811B46;
uint64_t rcx = 0x00000005;
uint64_t rdx = 0x001401A8;
uint64_t rsi = 0x0019F744;
uint64_t rdi = 0x00A022B8;
uint64_t rip = 0x00c6dab8;
uint64_t rsp = 0x0019F630;
uint64_t rbp = 0x00A2E676;
uint64_t r8 = 0x000000000019f5e8 ;
uint64_t r9 = 0x0000000000000000 ;
uint64_t r10 = 0x00000000ffffffff ;
uint64_t r11 = 0x0000000000000246 ;
uint64_t r12 = 0x000000000021d000 ;
uint64_t r13 = 0x000000000009fda0 ;
uint64_t r14 = 0x000000000009ed00 ;
uint64_t r15 = 0x00000000774f4770 ;
uint64_t rfl = 0x0000000000000206 ;
HANDLE FindProcessByName(const char* name)
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
return NULL;
}
if (Process32First(hProcessSnap, &pe32))
{
do
{
if (strcmp(pe32.szExeFile, name) == 0)
{
CloseHandle(hProcessSnap);
return OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
}
} while (Process32Next(hProcessSnap, &pe32));
}
CloseHandle(hProcessSnap);
return NULL;
}
/**
* [url=home.php?mod=space&uid=190858]@brief[/url] 枚举指定进程所有内存块
* [url=home.php?mod=space&uid=952169]@Param[/url] hProcess [in] 要枚举的进程,至少需拥有PROCESS_QUERY_INFORMATION权限
* @param memories [out] 返回枚举到的内存块数组
* [url=home.php?mod=space&uid=155549]@Return[/url] 成功返回true,失败返回false.
*/
int my_EnumAllMemoryBlocks(HANDLE hProcess, vector <MEMORY_BASIC_INFORMATION>& memories) {
if (hProcess == nullptr) return false;
// 初始化 vector 容量
memories.clear();
memories.reserve(200);
// 获取 PageSize 和地址粒度
SYSTEM_INFO sysInfo = { 0 };
GetSystemInfo(&sysInfo);
//遍历内存的指针p
const char* p = (const char*)sysInfo.lpMinimumApplicationAddress;
MEMORY_BASIC_INFORMATION memInfo = { 0 };
while (p < sysInfo.lpMaximumApplicationAddress) {
// 获取进程虚拟内存块缓冲区字节数
size_t size = VirtualQueryEx(
hProcess, // 进程句柄
p, // 要查询内存块的基地址指针
&memInfo, // 接收内存块信息的 MEMORY_BASIC_INFORMATION64 对象
sizeof(MEMORY_BASIC_INFORMATION) // 缓冲区大小
);
if (size != sizeof(MEMORY_BASIC_INFORMATION)) { break; }
memories.push_back(memInfo);
p += memInfo.RegionSize;
}
if (memories.size() == 0)
{
MessageBoxA(0, "枚举进程内存块时错误", "错误", MB_ICONWARNING | MB_TOPMOST | MB_OK);
}
return memories.size() > 0;
}
void PrintRegs()
{
printf("rax = %016llx\n", rax);
printf("rbx = %016llx\n", rbx);
printf("rcx = %016llx\n", rcx);
printf("rdx = %016llx\n", rdx);
printf("rsi = %016llx\n", rsi);
printf("rdi = %016llx\n", rdi);
printf("rsp = %016llx\n", rsp);
printf("rbp = %016llx\n", rbp);
printf("r8 = %016llx\n", r8);
printf("r9 = %016llx\n", r9);
printf("r10 = %016llx\n", r10);
printf("r11 = %016llx\n", r11);
printf("r12 = %016llx\n", r12);
printf("r13 = %016llx\n", r13);
printf("r14 = %016llx\n", r14);
printf("r15 = %016llx\n", r15);
printf("rip = %016llx\n", rip);
printf("rfl = %016llx\n", rfl);
}
void PrintStack()
{
DWORD stack[10];
uc_mem_read(uc, rsp, stack, 10 * sizeof(DWORD));
for (int i = 0; i < 16; i++)
{
printf("%016llx+%02x | %08x |\n", rsp, 4*i, stack[i]);
}
printf("\n");
}
void ReadRegs()
{
uc_reg_read(uc, UC_X86_REG_RAX, &rax);
uc_reg_read(uc, UC_X86_REG_RBX, &rbx);
uc_reg_read(uc, UC_X86_REG_RCX, &rcx);
uc_reg_read(uc, UC_X86_REG_RDX, &rdx);
uc_reg_read(uc, UC_X86_REG_RSI, &rsi);
uc_reg_read(uc, UC_X86_REG_RDI, &rdi);
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
uc_reg_read(uc, UC_X86_REG_RBP, &rbp);
uc_reg_read(uc, UC_X86_REG_R8, &r8);
uc_reg_read(uc, UC_X86_REG_R9, &r9);
uc_reg_read(uc, UC_X86_REG_R10, &r10);
uc_reg_read(uc, UC_X86_REG_R11, &r11);
uc_reg_read(uc, UC_X86_REG_R12, &r12);
uc_reg_read(uc, UC_X86_REG_R13, &r13);
uc_reg_read(uc, UC_X86_REG_R14, &r14);
uc_reg_read(uc, UC_X86_REG_R15, &r15);
uc_reg_read(uc, UC_X86_REG_RIP, &rip);
uc_reg_read(uc, UC_X86_REG_RFLAGS, &rfl);
}
void WriteRegs()
{
uc_reg_write(uc, UC_X86_REG_RAX, &rax);
uc_reg_write(uc, UC_X86_REG_RBX, &rbx);
uc_reg_write(uc, UC_X86_REG_RCX, &rcx);
uc_reg_write(uc, UC_X86_REG_RDX, &rdx);
uc_reg_write(uc, UC_X86_REG_RSI, &rsi);
uc_reg_write(uc, UC_X86_REG_RDI, &rdi);
uc_reg_write(uc, UC_X86_REG_RSP, &rsp);
uc_reg_write(uc, UC_X86_REG_RBP, &rbp);
uc_reg_write(uc, UC_X86_REG_R8, &r8);
uc_reg_write(uc, UC_X86_REG_R9, &r9);
uc_reg_write(uc, UC_X86_REG_R10, &r10);
uc_reg_write(uc, UC_X86_REG_R11, &r11);
uc_reg_write(uc, UC_X86_REG_R12, &r12);
uc_reg_write(uc, UC_X86_REG_R13, &r13);
uc_reg_write(uc, UC_X86_REG_R14, &r14);
uc_reg_write(uc, UC_X86_REG_R15, &r15);
uc_reg_write(uc, UC_X86_REG_RIP, &rip);
uc_reg_write(uc, UC_X86_REG_RFLAGS, &rfl);
}
uint64_t GetReg(const x86_reg& reg)
{
uint64_t value = 0;
switch (reg)
{
case X86_REG_RAX:uc_reg_read(uc, UC_X86_REG_RAX, &value);break;
case X86_REG_RBX:uc_reg_read(uc, UC_X86_REG_RBX, &value);break;
case X86_REG_RCX:uc_reg_read(uc, UC_X86_REG_RCX, &value);break;
case X86_REG_RDX:uc_reg_read(uc, UC_X86_REG_RDX, &value);break;
case X86_REG_RSI:uc_reg_read(uc, UC_X86_REG_RSI, &value);break;
case X86_REG_RDI:uc_reg_read(uc, UC_X86_REG_RDI, &value);break;
case X86_REG_RIP:uc_reg_read(uc, UC_X86_REG_RIP, &value);break;
case X86_REG_EFLAGS:uc_reg_read(uc, UC_X86_REG_RFLAGS, &value);break;
case X86_REG_RSP:uc_reg_read(uc, UC_X86_REG_RSP, &value);break;
case X86_REG_RBP:uc_reg_read(uc, UC_X86_REG_RBP, &value);break;
case X86_REG_R8:uc_reg_read(uc, UC_X86_REG_R8, &value);break;
case X86_REG_R9:uc_reg_read(uc, UC_X86_REG_R9, &value);break;
case X86_REG_R10:uc_reg_read(uc, UC_X86_REG_R10, &value);break;
case X86_REG_R11:uc_reg_read(uc, UC_X86_REG_R11, &value);break;
case X86_REG_R12:uc_reg_read(uc, UC_X86_REG_R12, &value);break;
case X86_REG_R13:uc_reg_read(uc, UC_X86_REG_R13, &value);break;
case X86_REG_R14:uc_reg_read(uc, UC_X86_REG_R14, &value);break;
case X86_REG_R15:uc_reg_read(uc, UC_X86_REG_R15, &value);break;
case X86_REG_EAX:uc_reg_read(uc, UC_X86_REG_EAX, &value);break;
case X86_REG_EBX:uc_reg_read(uc, UC_X86_REG_EBX, &value);break;
case X86_REG_ECX:uc_reg_read(uc, UC_X86_REG_ECX, &value);break;
case X86_REG_EDX:uc_reg_read(uc, UC_X86_REG_EDX, &value);break;
case X86_REG_ESI:uc_reg_read(uc, UC_X86_REG_RSI, &value); break;
case X86_REG_EDI:uc_reg_read(uc, UC_X86_REG_RDI, &value); break;
case X86_REG_EIP:uc_reg_read(uc, UC_X86_REG_RIP, &value); break;
case X86_REG_ESP:uc_reg_read(uc, UC_X86_REG_RSP, &value); break;
case X86_REG_EBP:uc_reg_read(uc, UC_X86_REG_RBP, &value); break;
case X86_REG_R8D:uc_reg_read(uc, UC_X86_REG_R8, &value); break;
case X86_REG_R9D:uc_reg_read(uc, UC_X86_REG_R9, &value); break;
case X86_REG_R10D:uc_reg_read(uc, UC_X86_REG_R10, &value); break;
case X86_REG_R11D:uc_reg_read(uc, UC_X86_REG_R11, &value); break;
case X86_REG_R12D:uc_reg_read(uc, UC_X86_REG_R12, &value); break;
case X86_REG_R13D:uc_reg_read(uc, UC_X86_REG_R13, &value); break;
case X86_REG_R14D:uc_reg_read(uc, UC_X86_REG_R14, &value); break;
case X86_REG_R15D:uc_reg_read(uc, UC_X86_REG_R15, &value); break;
case X86_REG_AX:uc_reg_read(uc, UC_X86_REG_EAX, &value); break;
case X86_REG_BX:uc_reg_read(uc, UC_X86_REG_EBX, &value); break;
case X86_REG_CX:uc_reg_read(uc, UC_X86_REG_ECX, &value); break;
case X86_REG_DX:uc_reg_read(uc, UC_X86_REG_EDX, &value); break;
case X86_REG_SI:uc_reg_read(uc, UC_X86_REG_RSI, &value); break;
case X86_REG_DI:uc_reg_read(uc, UC_X86_REG_RDI, &value); break;
case X86_REG_IP:uc_reg_read(uc, UC_X86_REG_RIP, &value); break;
case X86_REG_SP:uc_reg_read(uc, UC_X86_REG_RSP, &value); break;
case X86_REG_BP:uc_reg_read(uc, UC_X86_REG_RBP, &value); break;
case X86_REG_R8W:uc_reg_read(uc, UC_X86_REG_R8, &value); break;
case X86_REG_R9W:uc_reg_read(uc, UC_X86_REG_R9, &value); break;
case X86_REG_R10W:uc_reg_read(uc, UC_X86_REG_R10, &value); break;
case X86_REG_R11W:uc_reg_read(uc, UC_X86_REG_R11, &value); break;
case X86_REG_R12W:uc_reg_read(uc, UC_X86_REG_R12, &value); break;
case X86_REG_R13W:uc_reg_read(uc, UC_X86_REG_R13, &value); break;
case X86_REG_R14W:uc_reg_read(uc, UC_X86_REG_R14, &value); break;
case X86_REG_R15W:uc_reg_read(uc, UC_X86_REG_R15, &value); break;
default:assert(0);
}
return value;
}
bool ReadMemory(const uint64_t& addr, const DWORD& size, void* buf)
{
uc_error = uc_mem_read(uc, addr, buf, size);
if (uc_error != UC_ERR_OK) return false;
return true;
}
uint64_t GetMemAddr(const x86_op_mem& mem)
{
uint64_t addr = 0;
if (mem.base != X86_REG_INVALID)
{
addr += GetReg(mem.base);
}
if (mem.index != X86_REG_INVALID)
{
addr += GetReg(mem.index) * mem.scale;
}
addr += mem.disp;
return addr;
}
int main()
{
uc_error = uc_open(UC_ARCH_X86, UC_MODE_64, &uc);
if (uc_error != UC_ERR_OK) return -1;
if (cs_open(CS_ARCH_X86, CS_MODE_64, &cshandle) != CS_ERR_OK)
return -1;
if (cs_option(cshandle, CS_OPT_DETAIL, CS_OPT_ON) !=CS_ERR_OK)
return -1;
HANDLE hProcess = FindProcessByName("Project1.vmp.exe");
if (hProcess == NULL)
{
printf("FindProcessByName failed\n");
return -1;
}
vector<MEMORY_BASIC_INFORMATION> memories;
my_EnumAllMemoryBlocks(hProcess, memories);
for (int i = 0; i < memories.size(); ++i)
{
//if (memories[i].AllocationProtect == 0x00) continue;
printf("0x%08x-0x%08x ", memories[i].BaseAddress, (DWORD)memories[i].BaseAddress + memories[i].RegionSize);
DWORD oldProtect;
if (!ReadProcessMemory(hProcess, memories[i].BaseAddress, Buffer, memories[i].RegionSize, NULL))
{
printf("err\n");
continue;
}
uc_error = uc_mem_map(uc, (uint64_t)memories[i].BaseAddress, memories[i].RegionSize, UC_PROT_ALL);
if (uc_error != UC_ERR_OK)
{
printf("uc_mem_map err ");
continue;
}
uc_error = uc_mem_write(uc, (uint64_t)memories[i].BaseAddress, Buffer, memories[i].RegionSize);
if (uc_error != UC_ERR_OK)
{
printf("uc_mem_write err ");
continue;
}
printf("\n");
}
printf("Map success, monitor start.\n");
DWORD run_cnt = 0;
BYTE code[128];
DWORD patch = 0x4;
while(1)
{
WriteRegs();
uc_error = uc_mem_read(uc, rip, code, 128);
size_t count = cs_disasm(cshandle, code, 128, rip, 1, &insn);
//printf("%016llx %s %s\n", rip, insn->mnemonic, insn->op_str);
if (insn ->id == X86_INS_CPUID)
{
printf("[Special Insn] cpuid | %016llx %s %s\n", rip, insn->mnemonic, insn->op_str);
}
else if (insn ->id == X86_INS_RDTSC)
{
printf("[Special Insn] rdtsc | %016llx %s %s\n", rip, insn->mnemonic, insn->op_str);
}
else if (insn ->id == X86_INS_IN)
{
printf("[Special Insn] in | %016llx %s %s\n", rip, insn->mnemonic, insn->op_str);
}
else if (insn->id == X86_INS_OUT)
{
printf("[Special Insn] out | %016llx %s %s\n", rip, insn->mnemonic, insn->op_str);
}
else if (insn->id == X86_INS_SGDT)
{
printf("[Special Insn] sgdt | %016llx %s %s\n", rip, insn->mnemonic, insn->op_str);
}
else if (insn->id == X86_INS_SLDT)
{
printf("[Special Insn] sldt | %016llx %s %s\n", rip, insn->mnemonic, insn->op_str);
}
else if (insn->id == X86_INS_INT)
{
printf("[Special Insn] int | %016llx %s %s\n", rip, insn->mnemonic, insn->op_str);
}
else if (insn->id == X86_INS_SYSENTER)
{
printf("[Special Insn] sysenter | %016llx %s %s\n", rip, insn->mnemonic, insn->op_str);
}
else if (insn->id == X86_INS_SYSCALL)
{
printf("[Special Insn] syscall | %016llx %s %s\n", rip, insn->mnemonic, insn->op_str);
PrintRegs();
PrintStack();
}
else if (insn->id != X86_INS_LEA)
{
for (DWORD i = 0; i < insn->detail->x86.op_count; i++)
{
if (insn->detail->x86.operands[i].type == X86_OP_MEM)
{
uint64_t mem_addr = GetMemAddr(insn->detail->x86.operands[i].mem);
uint64_t value = 0;
if (mem_addr >= 0x10000 && mem_addr <= 0x200000) continue;
if (mem_addr >= 0x873000 && mem_addr <= 0x873000+0x427000 && i!=0) continue;
ReadMemory(mem_addr, insn->detail->x86.operands[i].size, &value);
printf("mem_addr = %016llx value = %016llx | %016llx %s %s\n", mem_addr, value, rip, insn->mnemonic, insn->op_str);
break;
}
}
}
cs_free(insn, 1);
uc_error = uc_emu_start(uc, rip, 0xffffffff, 0, 1);
if (uc_error) {
printf("Exception with error returned %u: %s\n",uc_error, uc_strerror(uc_error));
printf("%016llx %s %s\n", rip, insn->mnemonic, insn->op_str);
PrintRegs();
PrintStack();
break;
}
run_cnt++;
ReadRegs();
}
printf("run_cnt = %d\n", run_cnt);
}