首页
社区
课程
招聘
[旧帖] [邀请码已发][原创]inline hook + WriteProcessMemory 注入DLL 0.00雪花
发表于: 2011-6-14 18:35 2337

[旧帖] [邀请码已发][原创]inline hook + WriteProcessMemory 注入DLL 0.00雪花

2011-6-14 18:35
2337
(本文实现 windows核心编程 里面没有实现的 Dll注入)
1. 让进程生成一个被挂起的子进程
2. 从.exe模块的文件头中取得主线程起始内存地址
3. 将位于该内存地址处的机器指令保存起来
4. 强制将一些手工编写的机器指令写入到该内存地址.这些指令调用LoadLibrary装载一个Dll
5. 恢复子进程运行,让这些指令得到执行
6. 把保存起来的指令恢复到起始处
7. 让进程从起始地址继续执行,就好像什么都没有发生过一样
   汗!打了这么多子累死了

(注意了,这里用的方法要比书上说的好一些.  书上说只能是子进程才行! 本文的办法不是子进程照样能注入)

// 代码大致说明

1. 修理shellcode
2. 创建进程(打开其它进程,暂停其运行也行)
3. 写入shellcode到进程, 挂住线程将要执行的位置(不管是什么指令都可以挂钩,因为后shelcodel恢复钩子),
        保存挂钩处代码(为5个字节)到shellcode
        (下面的代码只是勾住入口点)
4. 释放线程

        //
        //
        //shellcode 执行 流程
        //

        //加载 你要注入的Dll
        IAT->_LoadLibraryA((LPCSTR)_relocal(inject_dllname));

        // 把堆栈中的返回点减5 (通过 堆栈参数 &argc -1 就是 ret 指令返回点的EIP)
        unsigned long *entry_esp = (unsigned long *)&argc;
        entry_esp --;
        // EIP 减 5 (就能返回到原来才行执行的位置了)
        *entry_esp -= 5;
       
        // 恢复挂钩处得代码
        void *pentry = (void *)(*entry_esp);
        void *entry_c = (void *)_relocal(original_entry);
        IAT->_WriteProcessMemory(
                IAT->_GetCurrentProcess(), pentry, entry_c, 5, NULL);

//==========================================================================
// shellcode 部分代码
// 具体编写参考 yuange 2001年的c语言直接直接生成  shellcode, 你用汇编也行
//===============================================================================



// manal jmp to main()
char jmp_main[] = "\xE9\0\0\0\0";

char original_entry[] = "original_entry";
char inject_dllname[0x100] = "inject_dllname";

char loadlibrary_str[] = "LoadLibraryA";


int main(int argc, char* argv[])
{
	_IMPORT_AT *IAT = (_IMPORT_AT *)_relocal(&g_IAT);

	// Initialize import address table by loadlibraryA
	InitializeIAT(_GetLoadLibraryA());
	
	IAT->_LoadLibraryA((LPCSTR)_relocal(inject_dllname));
	
	// sub return point, 5
	unsigned long *entry_esp = (unsigned long *)&argc;
	entry_esp --;
	*entry_esp -= 5;

	// revert hooked entry point code
	void *pentry = (void *)(*entry_esp);
	void *entry_c = (void *)_relocal(original_entry);
	IAT->_WriteProcessMemory(
		IAT->_GetCurrentProcess(), pentry, entry_c, 5, NULL);

	return 0;
}


//==========================================================================
//
// 注入完整代码
//
//=======================================================================

CWinApp theApp;

using namespace std;

UCHAR *_FixShellcode(LPCSTR lpszInjectFileName, ULONG *pEntry, LPCSTR lpszShellFileName, ULONG *pSize)
{
	//
	// lpszInjectFileName
	//
	HMODULE hModule = LoadLibraryEx(
		lpszInjectFileName, NULL, DONT_RESOLVE_DLL_REFERENCES);
	ASSERT(hModule);

	unsigned char *Image = (unsigned char *)hModule;
	
	PIMAGE_DOS_HEADER pimg_dos_h = (PIMAGE_DOS_HEADER)Image;
	PIMAGE_NT_HEADERS pimg_nt_h = (PIMAGE_NT_HEADERS)
		(Image+pimg_dos_h->e_lfanew);
	
	ULONG AddressOfEntryPoint = pimg_nt_h->OptionalHeader.ImageBase +
		pimg_nt_h->OptionalHeader.AddressOfEntryPoint;

	char entrycode[5];
	memcpy(entrycode, (Image+pimg_nt_h->OptionalHeader.AddressOfEntryPoint), 5);

	/// 汗! 调试的 时候居然会崩溃   在 ntdll
	FreeLibrary(hModule);


	//
	// lpszShellFileName 读取编译好的 Shellcode
	//
	HMODULE hModule2 = LoadLibraryEx(
		lpszShellFileName, NULL, DONT_RESOLVE_DLL_REFERENCES);
	ASSERT(hModule2);

	UCHAR *Image2 = (UCHAR *)hModule2;

	PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)Image2;

	PIMAGE_NT_HEADERS pImageNtHeader = (PIMAGE_NT_HEADERS)
							(Image2 + pImageDosHeader->e_lfanew);

	PIMAGE_SECTION_HEADER pImageSecHeader = (PIMAGE_SECTION_HEADER)
		(Image2 + pImageDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));

	ULONG sizeOfShell = pImageSecHeader->SizeOfRawData;

	UCHAR *c = new UCHAR[sizeOfShell];
	UCHAR *sectionAddress = (UCHAR *)
		(Image2 + pImageSecHeader->VirtualAddress);

	ULONG EntryOff = pImageNtHeader->OptionalHeader.AddressOfEntryPoint -
		pImageSecHeader->VirtualAddress;

	memcpy(c, sectionAddress, sizeOfShell);

	FreeLibrary(hModule2);
	
	//
	// Fix shell code
	//
	char *c2 = (char *)c;

	ASSERT(c2[0] == '\xE9');
	*(ULONG *)(&c2[1]) = EntryOff - 5;

	// For debug
	//c2[0] = '\xCC';	

	while(1)
	{
		if (stricmp(c2, "original_entry") == 0)
		{
			//保存挂钩处代码到 shellcode
			memcpy(c2, entrycode, 5);
		}
		
		if (stricmp(c2, "inject_dllname") == 0)
		{
			//复制 dll 完整路径 !..............................................
			memset(c2, 0x0,0x100);
			strcpy(c2, "dll.dll");
			break;
		}
		
		c2 ++;
	}
	
	//
	*pEntry = AddressOfEntryPoint;
	*pSize = sizeOfShell;
	return c;
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}

	const char szApplicationName[MAX_PATH] = "C:\\Program Files\\汗!.exe";

	char lpszModuleFileName[MAX_PATH] = {0};
	GetModuleFileNameA(NULL, lpszModuleFileName, MAX_PATH);
	CString szModuleFileName(lpszModuleFileName);
	szModuleFileName = szModuleFileName.Left(szModuleFileName.ReverseFind('\\'));

	// Shellcode PE 文件
	szModuleFileName += "\\c.bin";
	UCHAR *c = NULL;
	ULONG AddressOfEntryPoint;
	ULONG len ;
	c = _FixShellcode(szApplicationName, &AddressOfEntryPoint, szModuleFileName, &len);

	//
	//
	//
	char szCommandLine[0x400] = {0};
	strcpy(szCommandLine, szApplicationName);
	
	STARTUPINFO StartupInfo = {0};
	StartupInfo.cb = sizeof(STARTUPINFO);
	PROCESS_INFORMATION ProcessInformation;

	//	
	// 前面说了 你打开进程 暂停  获取 .Eip 也行 挂钩处发生变化!
	//

	if (!CreateProcess(szApplicationName, szCommandLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInformation)) 
	{
		//没释放资源   懒
		return FALSE;
	}
	

	LPVOID dst = VirtualAllocEx(ProcessInformation.hProcess, NULL, len, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

	// call
	char  call_c[5] = "\xE8";
	*((ULONG *)&call_c[1]) = (ULONG)dst - AddressOfEntryPoint - 5;

	WriteProcessMemory(ProcessInformation.hProcess, (LPVOID)AddressOfEntryPoint, call_c, 5, NULL);
	WriteProcessMemory(ProcessInformation.hProcess, (LPVOID)dst, c, len, NULL);
	
	
	BOOL bRetCode = ResumeThread(ProcessInformation.hThread);
	CloseHandle(ProcessInformation.hProcess);
	CloseHandle(ProcessInformation.hThread);

	delete[] c;

	return nRetCode;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
代码不错.......
2011-6-14 20:40
0
雪    币: 33
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
写的不错,看看
2011-6-16 10:20
0
游客
登录 | 注册 方可回帖
返回
//