基于asmjit的汇编代码注入工具实现

基于asmjit的汇编代码注入工具实现

实现功能

类似SPY++拖拽获取PID

拖拽获取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;
}

成品下载

X86
X64

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个使用C#编写的简单汇编代码注入程序的示例: ``` using System; using System.Diagnostics; using System.Runtime.InteropServices; namespace AssemblyInjection { class Program { static void Main(string[] args) { // 获取目标进程句柄 Process targetProcess = Process.GetProcessesByName("targetProcessName")[0]; IntPtr processHandle = OpenProcess(ProcessAccessFlags.All, false, targetProcess.Id); // 分配内存空间并将汇编代码写入其中 byte[] assemblyCode = new byte[] { 0xB8, 0x03, 0x00, 0x00, 0x00, 0xC3 }; // mov eax, 3; ret; IntPtr codeAddress = VirtualAllocEx(processHandle, IntPtr.Zero, assemblyCode.Length, AllocationType.Commit, MemoryProtection.ExecuteReadWrite); WriteProcessMemory(processHandle, codeAddress, assemblyCode, assemblyCode.Length, out IntPtr bytesWritten); // 创建远程线程并运行注入汇编代码 IntPtr threadId; IntPtr threadHandle = CreateRemoteThread(processHandle, IntPtr.Zero, 0, codeAddress, IntPtr.Zero, 0, out threadId); WaitForSingleObject(threadHandle, 0xFFFFFFFF); // 清理资源 CloseHandle(threadHandle); VirtualFreeEx(processHandle, codeAddress, 0, FreeType.Release); CloseHandle(processHandle); } [DllImport("kernel32.dll")] static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId); [DllImport("kernel32.dll")] static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, AllocationType flAllocationType, MemoryProtection flProtect); [DllImport("kernel32.dll")] static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")] static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out IntPtr lpThreadId); [DllImport("kernel32.dll")] static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds); [DllImport("kernel32.dll")] static extern bool CloseHandle(IntPtr hObject); [DllImport("kernel32.dll")] static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, FreeType dwFreeType); [Flags] enum ProcessAccessFlags : uint { All = 0x001F0FFF, Terminate = 0x00000001, CreateThread = 0x00000002, VirtualMemoryOperation = 0x00000008, VirtualMemoryRead = 0x00000010, VirtualMemoryWrite = 0x00000020, DuplicateHandle = 0x00000040, CreateProcess = 0x000000080, SetQuota = 0x00000100, SetInformation = 0x00000200, QueryInformation = 0x00000400, SuspendResume = 0x00000800, QueryLimitedInformation = 0x00001000, SetLimitedInformation = 0x00002000, AllAccess = 0x001F0FFF } [Flags] enum AllocationType { Commit = 0x1000, Reserve = 0x2000, Decommit = 0x4000, Release = 0x8000, Reset = 0x80000, TopDown = 0x100000, WriteWatch = 0x200000, Physical = 0x400000, LargePages = 0x20000000 } [Flags] enum MemoryProtection { Execute = 0x10, ExecuteRead = 0x20, ExecuteReadWrite = 0x40, ExecuteWriteCopy = 0x80, NoAccess = 0x01, ReadOnly = 0x02, ReadWrite = 0x04, WriteCopy = 0x08, GuardModifierflag = 0x100, NoCacheModifierflag = 0x200, WriteCombineModifierflag = 0x400 } [Flags] enum FreeType { Decommit = 0x4000, Release = 0x8000, } } } ``` 请注意,此示例仅用于演示目的,并且可能需要进行更改和适应您的特定情况。此外,汇编代码的内容也可能需要根据您的需求进行更改。最后,请确保您有足够的权限来执行此操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值