基于asmjit的汇编代码注入工具实现
实现功能
类似SPY++拖拽获取PID
X86和X64汇编代码机器码生成
打开或保存汇编代码
机器码注入
部分实现代码
生成机器码
void CCodeGeneraterDlg::GeneraterCode()
{
Environment environment = Environment::host();
Arch arch = environment.arch();
uint64_t baseAddress = Globals::kNoBaseAddress;
if (m_x86.GetCheck())
{
arch = Arch::kX86;
}
else if (m_x64.GetCheck())
{
arch = Arch::kX64;
}
else {
MessageBox("请选择架构");
}
char baseArg[256] = { 0 };
m_baseaddr.GetWindowText(baseArg,256);
hexToU64(baseAddress, baseArg, strlen(baseArg));
environment.setArch(arch);
StringLogger logger;
logger.addFlags(FormatFlags::kMachineCode);
CodeHolder code;
code.init(environment, baseAddress);
code.setLogger(&logger);
x86::Assembler a(&code);
AsmParser p(&a);
char input[4096] = { 0 };
m_asm.GetWindowText(input, 4096);
size_t size = strlen(input);
if (size > 0 && input[size - 1] == 0x0A)
input[--size] = 0;
string result;
m_asm.FmtLines(FALSE);
m_asm.GetWindowText(input, 4096);
logger.clear();
Error err = p.parse(input);
if (err == kErrorOk) {
const char* log = logger.data();
size_t i, size = logger.dataSize();
// Skip the instruction part, and keep only the comment part.
for (i = 0; i < size; i++) {
if (log[i] == ';') {
i += 2;
for (auto j = i; j < size; j++)
{
if (log[j] == '\n')
{
result.append(log + i, log + j);
break;
}
}
result.append("\r\n");
}
}
}
m_binary.SetWindowText(result.c_str());
}
打开文件
BOOL CCodeGeneraterDlg::OnFileOpen()
{
OPENFILENAME ofn = { 0 };
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
CHAR szFile[256] = "";
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0ASM\0*.asm";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
GetOpenFileName(&ofn);
HANDLE hFile = CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (!hFile)
{
return FALSE;
}
DWORD length = GetFileSize(hFile, NULL);
CHAR* buff = (CHAR*)malloc(length);
if (!buff)
{
return FALSE;
}
if (!ReadFile(hFile, buff, length, NULL, NULL))
{
return FALSE;
}
m_asm.SetWindowText(buff);
CloseHandle(hFile);
free(buff);
return TRUE;
}
保存文件
BOOL CCodeGeneraterDlg::OnFileSave()
{
OPENFILENAME ofn = { 0 };
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
CHAR filename[256] = "";
ofn.lpstrFile = filename;
ofn.nMaxFile = sizeof(filename);
ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0ASM\0*.asm\0";
ofn.lpstrDefExt = "asm";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_CREATEPROMPT | OFN_LONGNAMES;
GetSaveFileName(&ofn);
HANDLE hFile = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (!hFile)
{
return FALSE;
}
size_t length = m_asm.GetWindowTextLength();
CHAR* buff = (CHAR*)malloc(length + 1);
if (!buff)
{
return FALSE;
}
m_asm.GetWindowText(buff, (int)length + 1);
if (!WriteFile(hFile, buff, (DWORD)strlen(buff), NULL, NULL))
{
return FALSE;
}
CloseHandle(hFile);
free(buff);
return TRUE;
}
注入代码
BOOL CCodeGeneraterDlg::CodeReject()
{
Environment environment = Environment::host();
Arch arch = environment.arch();
uint64_t baseAddress = Globals::kNoBaseAddress;
if (m_x86.GetCheck())
{
arch = Arch::kX86;
}
else if (m_x64.GetCheck())
{
arch = Arch::kX64;
}
else {
MessageBox("请选择架构");
}
HANDLE hProcess = 0;
char szpid[256] = { 0 };
m_Pid.GetWindowText(szpid,256);
DWORD pid = StrToInt(szpid);
//hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, pid);
NtOpenProcess = (pfNtOpenProcess)GetProcAddr(L"ntdll.dll", "NtOpenProcess");
if (!NtOpenProcess)
{
return FALSE;
}
CLIENT_ID client = { 0 };
client.UniqueProcess = (HANDLE)pid;
OBJECT_ATTRIBUTES oa = { 0 };
oa.Length = sizeof(oa);
NtOpenProcess(&hProcess, GENERIC_ALL, &oa, &client);
if (!hProcess)
{
return FALSE;
}
BOOL target = FALSE;
BOOL src = FALSE;
IsWow64Process(GetCurrentProcess(), &src);
IsWow64Process(hProcess, &target);
NtAllocateVirtualMemory = (pfNtAllocateVirtualMemory)GetProcAddr(L"ntdll.dll", "NtAllocateVirtualMemory");
NtWow64AllocateVirtualMemory64 = (pfNtWow64AllocateVirtualMemory64)GetProcAddr(L"ntdll.dll", "NtWow64AllocateVirtualMemory64");
if (!NtAllocateVirtualMemory)
{
return 0;
}
ULONG64 baseAddr = NULL;
ULONG64 allocSize = 4096;
if (src == TRUE && target == FALSE)
{
NtWow64AllocateVirtualMemory64(hProcess, &baseAddr, NULL, &allocSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
}
else
{
NtAllocateVirtualMemory(hProcess, (PVOID*)&baseAddr, NULL, (PSIZE_T)&allocSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
}
if (!baseAddr)
{
return 0;
}
// TODO: 在此添加控件通知处理程序代码
baseAddress = (uint64_t)baseAddr;
CString str;
str.Format("%08llX", baseAddress);
m_baseaddr.SetWindowText(str);
environment.setArch(arch);
StringLogger logger;
logger.addFlags(FormatFlags::kMachineCode);
CodeHolder code;
code.init(environment, baseAddress);
code.setLogger(&logger);
x86::Assembler a(&code);
AsmParser p(&a);
char input[4096] = { 0 };
m_asm.GetWindowText(input, 4096);
size_t size = strlen(input);
if (size > 0 && input[size - 1] == 0x0A)
input[--size] = 0;
string result;
m_asm.FmtLines(FALSE);
m_asm.GetWindowText(input, 4096);
logger.clear();
Error err = p.parse(input);
if (err == kErrorOk) {
const char* log = logger.data();
size_t i, size = logger.dataSize();
// Skip the instruction part, and keep only the comment part.
for (i = 0; i < size; i++) {
if (log[i] == ';') {
i += 2;
for (auto j = i; j < size; j++)
{
if (log[j] == '\n')
{
result.append(log + i, log + j);
break;
}
}
result.append("\r\n");
}
}
}
m_binary.SetWindowText(result.c_str());
BYTE hexdata[4096] = { 0 };
StrToHex(result.c_str(), hexdata);
NtWriteVirtualMemory = (pfNtWriteVirtualMemory)GetProcAddr(L"ntdll.dll", "NtWriteVirtualMemory");
NtWow64WriteVirtualMemory64 = (pfNtWow64WriteVirtualMemory64)GetProcAddr(L"ntdll.dll", "NtWow64WriteVirtualMemory64");
if (!NtWriteVirtualMemory)
{
return 0;
}
if (src == TRUE && target == FALSE)
{
NtWow64WriteVirtualMemory64(hProcess, (PVOID64)baseAddr, hexdata, 4096, NULL);
}
else {
NtWriteVirtualMemory(hProcess, (PVOID)baseAddr, hexdata, 4096, NULL);
}
NtCreateThreadEx = (pfNtCreateThreadEx)GetProcAddr(L"ntdll.dll", "NtCreateThreadEx");
if (!NtCreateThreadEx)
{
return FALSE;
}
HANDLE hThread = 0;
NtCreateThreadEx(&hThread, GENERIC_ALL, NULL, hProcess, (LPTHREAD_START_ROUTINE)baseAddr, NULL, 0, 0, 0, 0, NULL);
//HANDLE hThread = CreateRemoteThreadEx(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)baseAddr, NULL, 0, NULL, NULL);
if (!hThread)
{
NtFreeVirtualMemory = (pfNtFreeVirtualMemory)GetProcAddr(L"ntdll.dll", "NtFreeVirtualMemory");
if (!NtFreeVirtualMemory)
{
return FALSE;
}
SIZE_T freeSize = 0;
NtFreeVirtualMemory(hProcess, (PVOID*)&baseAddr, &freeSize, MEM_RELEASE);
return FALSE;
}
NtWaitForSingleObject = (pfNtWaitForSingleObject)GetProcAddr(L"ntdll.dll", "NtWaitForSingleObject");
if (!NtWaitForSingleObject)
{
return FALSE;
}
LARGE_INTEGER time = { 0 };
time.QuadPart = -1;
NtWaitForSingleObject(hThread,NULL,&time);
NtFreeVirtualMemory = (pfNtFreeVirtualMemory)GetProcAddr(L"ntdll.dll", "NtFreeVirtualMemory");
if (!NtFreeVirtualMemory)
{
return FALSE;
}
SIZE_T freeSize = 0;
NtFreeVirtualMemory(hProcess, (PVOID*)&baseAddr, &freeSize, MEM_RELEASE);
return TRUE;
}