zoukankan      html  css  js  c++  java
  • 逆向工程核心原理——第三十二章

    计算器显示中文数字

    此实验中使用的代码只适用于x86系统。

    本章讲解API钩取技术时将以Windows计算器( calc.exe)为示例,向计算器进程插人用户的
    DLL文件,钩取IAT的user32.SetWindowTextW() API地址。

    SetWindowTextW() API的作用是显示计算器中的数字,而我们会将这个数字改为中文数字。

    我们知道,当程序需要调用源程序之外的函数时,需要访问导入表(IAT),IAT中存放着需要调用的函数的地址,而这次的实验,我们就需要钩出这个地址,替换成别的地址,从而使阿拉伯数字变为汉字数字。

    我们在图中可以看到:

    这里计算器(cala.exe)运行到01002628时调用user32.dll,调用完成后回到cala.exe

    而我们修改后的运行顺序为:

    EXE:

    //InjectDll.exe
    
    #include "stdio.h"  
    #include "windows.h"  
    #include "tlhelp32.h"  
    #include "winbase.h"  
    #include "tchar.h"  
    #include<iostream>
    using namespace std;
    
    void usage()
    {
    	printf("
    InjectDll.exe by ReverseCore
    "
    		"- USAGE : InjectDll.exe <i|e> <PID> <dll_path>
    
    ");
    }
    
    
    BOOL InjectDll(DWORD dwPID, LPCTSTR szDllName)
    {
    	HANDLE hProcess, hThread;
    	LPVOID pRemoteBufferData;  //远程进程中的内存
    	DWORD dwBufSize = (DWORD)(_tcslen(szDllName) + 1) * sizeof(TCHAR);
    	LPTHREAD_START_ROUTINE pThreadProc;
    
    	if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
    	{
    		DWORD dwErr = GetLastError();
    		return FALSE;
    	}
    
    	//申请内存 可读可写
    	pRemoteBufferData = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
    
    	//像内存写入dll路径
    	WriteProcessMemory(hProcess, pRemoteBufferData, (LPVOID)szDllName, dwBufSize, NULL);
    
    	//获得loadlibraryw地址
    	pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
    
    	//创建远程线程
    	hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBufferData, 0, NULL);
    	WaitForSingleObject(hThread, INFINITE);
    
    	CloseHandle(hThread);
    	CloseHandle(hProcess);
    
    	return TRUE;
    }
    
    
    BOOL EjectDll(DWORD dwPID, LPCTSTR szDllName)
    {
    	BOOL bMore = FALSE, bFound = FALSE;
    	HANDLE hSnapshot, hProcess, hThread;
    	MODULEENTRY32 me = { sizeof(me) };
    	LPTHREAD_START_ROUTINE pThreadProc;
    
    	if (INVALID_HANDLE_VALUE == (hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID)))
    	{
    		return FALSE;
    	}
    
    
    	bMore = Module32First(hSnapshot, &me);
    	for (; bMore; bMore = Module32Next(hSnapshot, &me))
    	{
    		if (!_tcsicmp(me.szModule, szDllName) || !_tcsicmp(me.szExePath, szDllName))
    		{
    			bFound = TRUE;
    			break;
    		}
    	}
    
    	if (!bFound)
    	{
    		CloseHandle(hSnapshot);
    		return FALSE;
    	}
    
    	if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
    	{
    		CloseHandle(hSnapshot);
    		return FALSE;
    	}
    
    	pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "FreeLibrary");
    	hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, me.modBaseAddr, 0, NULL);
    	WaitForSingleObject(hThread, INFINITE);
    
    	CloseHandle(hThread);
    	CloseHandle(hProcess);
    	CloseHandle(hSnapshot);
    
    	return TRUE;
    }
    
    
    DWORD _EnableNTPrivilege(LPCTSTR szPrivilege, DWORD dwState)
    {
    	DWORD dwRtn = 0;
    	HANDLE hToken;
    	if (OpenProcessToken(GetCurrentProcess(),
    		TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    	{
    		LUID luid;
    		if (LookupPrivilegeValue(NULL, szPrivilege, &luid))
    		{
    			BYTE t1[sizeof(TOKEN_PRIVILEGES) + sizeof(LUID_AND_ATTRIBUTES)];
    			BYTE t2[sizeof(TOKEN_PRIVILEGES) + sizeof(LUID_AND_ATTRIBUTES)];
    			DWORD cbTP = sizeof(TOKEN_PRIVILEGES) + sizeof(LUID_AND_ATTRIBUTES);
    
    			PTOKEN_PRIVILEGES pTP = (PTOKEN_PRIVILEGES)t1;
    			PTOKEN_PRIVILEGES pPrevTP = (PTOKEN_PRIVILEGES)t2;
    
    			pTP->PrivilegeCount = 1;
    			pTP->Privileges[0].Luid = luid;
    			pTP->Privileges[0].Attributes = dwState;
    
    			if (AdjustTokenPrivileges(hToken, FALSE, pTP, cbTP, pPrevTP, &cbTP))
    				dwRtn = pPrevTP->Privileges[0].Attributes;
    		}
    
    		CloseHandle(hToken);
    	}
    
    	return dwRtn;
    }
    
    
    int _tmain(int argc, TCHAR* argv[])
    {
    	if (argc != 4)
    	{
    		usage();
    		return 1;
    	}
    
    	// adjust privilege  
    	_EnableNTPrivilege(SE_DEBUG_NAME, SE_PRIVILEGE_ENABLED);
    
    	// InjectDll.exe <i|e> <PID> <dll_path>  
    	if (!_tcsicmp(argv[1], L"i"))
    	{
    		InjectDll((DWORD)_tstoi(argv[2]), argv[3]);
    	}
    	else if (!_tcsicmp(argv[1], L"e"))
    	{
    		EjectDll((DWORD)_tstoi(argv[2]), argv[3]);
    	}
    
    
    	return 0;
    }
    

    DLL:

    //hookiat.dll
    
    #include "stdio.h"  
    #include "wchar.h"  
    #include "windows.h"  
    
    
    // typedef  
    typedef BOOL(WINAPI* PFSETWINDOWTEXTW)(HWND hWnd, LPWSTR lpString); //SetWindowsTextW()的地址
    
    
    // 原函数地址
    FARPROC g_pOrginalFunction = NULL;
    
    
    BOOL WINAPI MySetWindowTextW(HWND hWnd, LPWSTR lpString)
    {
    	wchar_t* pNum = L"零一二三四五六七八九";
    	wchar_t temp[2] = { 0, };
    	int i = 0, nLen = 0, nIndex = 0;
    
    	nLen = wcslen(lpString);
    	for (i = 0; i < nLen; i++)
    	{
    		//   将阿拉伯数字转换为中文数字  
    		//   lpString是宽字符版本(2个字节)字符串  
    		if (L'0' <= lpString[i] && lpString[i] <= L'9')
    		{
    			temp[0] = lpString[i];
    			nIndex = _wtoi(temp);
    			lpString[i] = pNum[nIndex];
    		}
    	}
    
    	//   调用原函数;user32.SetWindowTextW  
    	//   (修改lpString缓冲区中的内容)  
    	return ((PFSETWINDOWTEXTW)g_pOrginalFunction)(hWnd, lpString);
    }
    
    /**********************************/
    //    函数名:hook_iat
    //	  功能  :负责实施IAT钩取的核心函数
    /**********************************/
    BOOL hook_iat(LPCSTR szDllName, PROC pfnOrg, PROC pfnNew)
    {
    	HMODULE hMod;
    	LPCSTR szLibName;
    	PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
    	PIMAGE_THUNK_DATA pThunk;
    	DWORD dwOldProtect, dwRVA;
    	PBYTE pAddr;
    
    	// hMod, pAddr = ImageBase of calc.exe  
    	//             = VA to MZ signature (IMAGE_DOS_HEADER)  
    	hMod = GetModuleHandle(NULL);
    	pAddr = (PBYTE)hMod;
    
    	// pAddr = VA to PE signature (IMAGE_NT_HEADERS)  
    	pAddr += *((DWORD*)&pAddr[0x3C]);
    
    	// dwRVA = RVA to IMAGE_IMPORT_DESCRIPTOR Table  
    	dwRVA = *((DWORD*)&pAddr[0x80]);
    
    	// pImportDesc = VA to IMAGE_IMPORT_DESCRIPTOR Table  
    	pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hMod + dwRVA);
    
    	for (; pImportDesc->Name; pImportDesc++)
    	{
    		// szLibName = VA to IMAGE_IMPORT_DESCRIPTOR.Name  
    		szLibName = (LPCSTR)((DWORD)hMod + pImportDesc->Name);
    		if (!_stricmp(szLibName, szDllName))
    		{
    			// pThunk = IMAGE_IMPORT_DESCRIPTOR.FirstThunk  
    			//        = VA to IAT(Import Address Table)  
    			pThunk = (PIMAGE_THUNK_DATA)((DWORD)hMod +
    				pImportDesc->FirstThunk);
    
    			// pThunk->u1.Function = VA to API  匹配成功
    			for (; pThunk->u1.Function; pThunk++)
    			{
    				if (pThunk->u1.Function == (DWORD)pfnOrg)
    				{
    					// 更改为可读写模式  
    					VirtualProtect((LPVOID)&pThunk->u1.Function,
    						4,
    						PAGE_EXECUTE_READWRITE,
    						&dwOldProtect);
    
    					// 修改IAT的值  
    					pThunk->u1.Function = (DWORD)pfnNew;
    
    					//修改完成后,恢复原保护属性
    					VirtualProtect((LPVOID)&pThunk->u1.Function,
    						4,
    						dwOldProtect,
    						&dwOldProtect);
    
    					return TRUE;
    				}
    			}
    		}
    	}
    
    	return FALSE;
    }
    
    
    
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
    	switch (fdwReason)
    	{
    	case DLL_PROCESS_ATTACH:
    		// 保存原始API的地址  
    		g_pOrginalFunction = GetProcAddress(GetModuleHandle(L"user32.dll"),
    			"SetWindowTextW");
    
    		// # hook  
    		//   用hookiat.MySetWindowText钩取user32.SetWindowTextW  
    		hook_iat("user32.dll", g_pOrginalFunction, (PROC)MySetWindowTextW);
    		break;
    
    	case DLL_PROCESS_DETACH:
    		// # unhook  
    		//   将calc.exe的IAT恢复原值  
    		hook_iat("user32.dll", (PROC)MySetWindowTextW, g_pOrginalFunction);
    		break;
    	}
    
    	return TRUE;
    }
    
  • 相关阅读:
    Javascript FP-ramdajs
    微信小程序开发
    SPA for HTML5
    One Liners to Impress Your Friends
    Sass (Syntactically Awesome StyleSheets)
    iOS App Icon Template 5.0
    React Native Life Cycle and Communication
    Meteor framework
    RESTful Mongodb
    Server-sent Events
  • 原文地址:https://www.cnblogs.com/lex-shoukaku/p/13786385.html
Copyright © 2011-2022 走看看