搞定自己的汇编注入工具

Home / Article MrLee 2016-4-13 3076

去年有段时间研究搞自己的汇编代码注入,但是从来不曾搞过,所以一头雾水就放置一边了。时隔一年,看到看雪论坛有人开源了一个代码注入工具,自己封装了ollydbg的开源库。然后简单看了下,不过还是想自己搞。查了下资源,先要用引擎,这里我用的是ollydbg的汇编引擎,下载地址:disasm 我下载的是最新的。然后创建一个VC工程,窗口化的。然后main.c代码如下:
#include 
#define MAINPROG
#include "disasm.h"

void testAssemble(char *pasm)
{
	// Old form. So what?
	int j = 0,n = 0,i = 0;
	t_asmmodel am = {0};
	char errtext[TEXTLEN],s[TEXTLEN];
	// Assemble one of the commands above. First try form with 32-bit immediate.
	j = Assemble(pasm,0x400000,&am,0,0,errtext);
	//n = sprintf(s,"%3i  ",j);
	for (i=0; i<j; i++){
		if(i != j -1)
			n+=sprintf(s+n,"0x%02X,",am.code[i] & 0xFF);
		else
			n+=sprintf(s+n,"0x%02X",am.code[i] & 0xFF);
	}
	if (j<=0) 
		sprintf(s+n,"  error=\"%s\"",errtext);
	printf("%s,",s);
}
void main(void) 
{
	testAssemble("pushad");
	testAssemble("mov eax,456D68");
	testAssemble("mov eax,[eax]");
	testAssemble("mov edx,453040");
	//call 00452E98
	testAssemble("mov ebx,452E98");
	testAssemble("call ebx");
	testAssemble("popad");
	testAssemble("retn");
	getchar();
};

结果:

20160413121646


不过代码注入最后要注意,要加一个retn值,否则目标程序会挂掉。据看雪上面说,IDE在我们编译一个void func的时候,其实默认是给我们加上了return,所以这里我们也要手动加上一个retn值。
下面是注入核心代码
BOOL CMemHelperDlg::EnableDebugPriv(void)
{
	HANDLE hToken;
	LUID sedebugnameValue; 
	TOKEN_PRIVILEGES tkp; 
	if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS, &hToken)) 
	{
		AfxMessageBox("error code:1");
		return FALSE; 
	}
	if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) 
	{ 
		CloseHandle( hToken ); 
		AfxMessageBox("error code:2");
		return FALSE; 
	} 
	tkp.PrivilegeCount = 1; 
	tkp.Privileges[0].Luid = sedebugnameValue; 
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
	if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL)) 
	{
		AfxMessageBox("error code:3");
		CloseHandle( hToken );
		return FALSE; 
	}
	return TRUE;
}
DWORD CMemHelperDlg::RemoteCall(HWND hwnd,DWORD mSize,byte* pData)
{
	if(hwnd == NULL)
	{
		AfxMessageBox("请先初始窗口句柄!");
		return 0;
	}
	DWORD dwPid;
	::GetWindowThreadProcessId(hwnd,&dwPid);
	HANDLE handle=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPid);
	if(NULL == handle)
	{
		AfxMessageBox("代码内存申请失败");
		return 0;
	}
	LPVOID lpThreadBase;
	DWORD dwThreadSize;
	DWORD dwThreadId=0;
	HANDLE hThread;
	//申请内存
	lpThreadBase=VirtualAllocEx(handle,NULL,mSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	if(NULL == lpThreadBase)
	{
		AfxMessageBox("代码内存申请失败");
		return 0;
	}
	__try{
		if(NULL!=lpThreadBase){
			//将代码写入内存
			if (!WriteProcessMemory(handle,lpThreadBase,pData,mSize,&dwThreadSize))
			{
				VirtualFreeEx(handle,lpThreadBase,mSize,MEM_RELEASE); 
				return 0;
			}
			//创建目标进程远程线程 执行代码
			hThread = CreateRemoteThread(handle,NULL,NULL,(LPTHREAD_START_ROUTINE)lpThreadBase,NULL,0,&dwThreadId);
			DWORD errorCode = GetLastError();
			WaitForSingleObject(hThread, INFINITE);
		}
	}__finally{
		VirtualFreeEx(handle,lpThreadBase,mSize,MEM_RELEASE);
		CloseHandle(hThread);
		CloseHandle(handle);
	}
	if(dwThreadId>0){
		return TRUE;
	}
	return FALSE;
}
void CMemHelperDlg::OnBnClickedBtnTest()
{
	// TODO: 在此添加控件通知处理程序代码
	CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_ASM);
	int nCount = pEdit->GetLineCount();
	BYTE buf[2018] = {0};//要写入的shell代码
	int bufIndex = 0;
	for (int i=0;i<nCount;i++) { t_asmmodel t_asm; char szError[512] = {0}; char szLine[256] = {0}; pEdit->GetLine(i,szLine,sizeof(szLine));
		Assemble(szLine,0x400000,&t_asm,0,0,szError);
		if (t_asm.length <= 0)
		{
			MessageBox(szError);
			return;
		}
		//char tmp[256] = {0};
		//int tempIndex = 0;
		//for (int j=0;j<t_asm.length;j++)
		//	tempIndex += sprintf_s(tmp+tempIndex,256-tempIndex,"%0X",t_asm.code[j]&0xFF);
		//println("%s",tmp);
		memcpy(buf+bufIndex,t_asm.code,t_asm.length);
		bufIndex += t_asm.length;
	}
	buf[bufIndex++] = 0xC3;//retn 不加目标程序自动退出
	RemoteCall(m_tempHwnd,bufIndex,buf);
}

本文链接:https://www.it72.com/9149.htm

推荐阅读
最新回复 (0)
返回