怎么才能HOOK到其他的进程

ssr奥利奥 2015-12-14 10:50:05
我有一个进程:

#include <windows.h>
#pragma comment(lib,"user32.lib")
void main(){
while(1){
MessageBoxA(NULL,"hello","msg",MB_OK);
}

}


已知这个hello.exe的PID值 怎么才能HOOK到这个进程 让"hello"变成我想要的语句 比如“我HOOK到了”


#include <windows.h>
#pragma comment(lib,"user32.lib")

typedef int (__stdcall *pOldMBox)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption,UINT uType);
pOldMBox pMBox = NULL;

int __stdcall MyMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption,UINT uType)
{
return pMBox(NULL,"i'm hacked","hello",MB_OK);
}
BOOL CompStr(LPSTR s1, LPSTR s2)
{
PCHAR p, q;
for (p = s1, q = s2; (*p != 0) && (*q != 0); p++, q++) {
if (*p != *q) return FALSE;
}
return TRUE;
}
int myHook()
{
DWORD dwBase;
LPCSTR lpszFuncName;
lpszFuncName="MessageBoxA";
HMODULE hMod = GetModuleHandle(NULL);
dwBase = (DWORD)hMod;
DWORD dwRVAImpTbl;
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS pNtHeaders;
PIMAGE_OPTIONAL_HEADER32 pOptHeader;
PIMAGE_IMPORT_DESCRIPTOR pImpTbl;
PIMAGE_THUNK_DATA pthunk1, pthunk2;
PIMAGE_IMPORT_BY_NAME pOrdinalName;
pDosHeader = (PIMAGE_DOS_HEADER)dwBase;
pNtHeaders = (PIMAGE_NT_HEADERS)(dwBase + pDosHeader->e_lfanew);
pOptHeader = &(pNtHeaders->OptionalHeader);
dwRVAImpTbl = pOptHeader->DataDirectory[1].VirtualAddress;
pImpTbl = (PIMAGE_IMPORT_DESCRIPTOR)(dwBase + dwRVAImpTbl);

while(pImpTbl->FirstThunk){
pthunk1 = (PIMAGE_THUNK_DATA) (dwBase + pImpTbl->OriginalFirstThunk);
pthunk2 = (PIMAGE_THUNK_DATA) (dwBase + pImpTbl->FirstThunk);
while(pthunk1->u1.Function){
pOrdinalName = (PIMAGE_IMPORT_BY_NAME) (dwBase + pthunk1->u1.AddressOfData);
if (CompStr((LPSTR)lpszFuncName, (LPSTR)&pOrdinalName->Name)){
MEMORY_BASIC_INFORMATION mbi_thunk;
VirtualQuery(pthunk2, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION)); //查询地址空间中内存地址的信息
DWORD dwOLD;
VirtualProtect(pthunk2,sizeof(DWORD),PAGE_READWRITE,&dwOLD);
pMBox =(pOldMBox)(pthunk2->u1.Function);
pthunk2->u1.Function = (DWORD)MyMessageBox;
VirtualProtect(pthunk2,sizeof(DWORD),dwOLD,0);
break;
}
pthunk1++;
pthunk2++;
}
pImpTbl++;
}
return 0;
}
int main()
{
MessageBoxA(NULL, "hello", "msg", MB_OK);
myHook();
MessageBoxA(NULL, "hello", "msg", MB_OK);
}


这个是我写的HOOK本进程 怎么修改才能变成HOOK指定PID的进程呢?
也可以不用修改我这个进程,重新写一个。。
...全文
278 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
ProgrammingRing 2015-12-16
  • 打赏
  • 举报
回复
OpenProcess
ReadProcessMemory
WriteProcessMemory
赵4老师 2015-12-16
  • 打赏
  • 举报
回复
提醒:再牛×的老师也无法代替学生自己领悟和上厕所! 仅供参考:
/*
    Application:    Code Injection in Explorer
    Author:     @_RT
    Compiled on:    Feb 2014
    URL:http://www.codeproject.com/Tips/732044/Code-Injection-2

    We will see the different steps involved to perform a code injection into an already running process.

    Following are the quick steps through the process of injection.
    1.Get the API addresses that you will be calling from the injected code.
    2.Prepare shell code of your function that you want to get executed from the injected process.
    3.Get the process ID of the running process that you wish to inject into by enumerating through the
      list of processes or by finding the process's window (in case it's a GUI application) by class name or title.
    4.Open the process using its Pid with All Access rights.
    5.Allocate different memory spaces in the process that you are going to inject to with desired access
      rights for holding different segments of your shell code.
        Code part (executable instructions)
        Data part (strings, function parameters, etc.)
    6.Write the allocated memories with the respective values (code and data).
    7.Call CreateRemoteThread API and pass to it the start of allocated memory address where you have
      written your shell code from the process we are injecting.
*/

#include <windows.h>
#pragma comment(lib,"user32.lib")

LPVOID addr;
LPVOID addr2;

BOOL InjectExecutable(DWORD dwPid,LPVOID si,LPVOID pi,int sisize,int pisize)
{
    LPVOID hNewModule;
    HANDLE hProcess;
    CHAR S[]    = { "C:\\Windows\\notepad.exe" };
    BYTE byt[]  = {0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x01, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x68};
    BYTE byt2[] = {0xE8};
    BYTE byt3[] = {0x68};

    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
    if (hProcess == NULL)
    {
        return FALSE;
    }

    LPVOID staddr = VirtualAllocEx(hProcess, NULL, sizeof(S), MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, staddr, S, sizeof(S), NULL);
    LPVOID fnaddr = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, fnaddr, si, sisize, NULL);
    LPVOID fnaddr2 = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, fnaddr2, pi, pisize, NULL);

    hNewModule = VirtualAllocEx(hProcess, NULL, 100, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (hNewModule == NULL)
    {
        return FALSE;
    }
    LPTHREAD_START_ROUTINE strtaddr = (LPTHREAD_START_ROUTINE)hNewModule;

    WriteProcessMemory(hProcess, hNewModule, byt3, sizeof(byt3), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt3));
    WriteProcessMemory(hProcess, hNewModule, &fnaddr, sizeof(fnaddr), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(fnaddr));
    WriteProcessMemory(hProcess, hNewModule, byt3, sizeof(byt3), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt3));
    WriteProcessMemory(hProcess, hNewModule, &fnaddr2, sizeof(fnaddr2), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(fnaddr2));
    WriteProcessMemory(hProcess, hNewModule, byt, sizeof(byt), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt));
    WriteProcessMemory(hProcess, hNewModule, &staddr, sizeof(staddr), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(staddr));
    WriteProcessMemory(hProcess, hNewModule, byt2, sizeof(byt2), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt2));
    addr = (LPVOID)((int)addr - ((int)hNewModule + 4));
    WriteProcessMemory(hProcess, hNewModule, &addr, sizeof(addr), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(addr));
    WriteProcessMemory(hProcess, hNewModule, byt, 2, NULL);
    hNewModule = (LPVOID)((int)hNewModule + 2);
    WriteProcessMemory(hProcess, hNewModule, byt2, sizeof(byt2), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt2));
    addr2 = (LPVOID)((int)addr2 - ((int)hNewModule + 4));
    WriteProcessMemory(hProcess, hNewModule, &addr2, sizeof(addr2), NULL);

    CreateRemoteThread(hProcess, 0, 0, strtaddr, NULL, 0, NULL);
    return TRUE;
}

void main()
{
    _STARTUPINFOA si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    DWORD dwPid;
    HMODULE ldlib = LoadLibraryA("Kernel32.dll");
    addr = GetProcAddress(ldlib, "CreateProcessA");
    addr2 = GetProcAddress(ldlib, "ExitThread");
    GetWindowThreadProcessId(FindWindow(NULL, L"Start Menu"), &dwPid);

    InjectExecutable(dwPid,&si,&pi,sizeof(si),sizeof(pi));
}
fly_dragon_fly 2015-12-15
  • 打赏
  • 举报
回复
用一下detours好了
ssr奥利奥 2015-12-15
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
Detours库是开源的,这个库的功能就是“读取对方进程内存地址,将指向MessageBoxA的地址转换成指向MyMessageBoxA的”。 你高兴了把它的部分代码拷贝到你的代码中调通就行。
能不能把我上面的程序做成一个线程 注入到目标MessageBoxA里面呢
赵4老师 2015-12-15
  • 打赏
  • 举报
回复
Detours库是开源的,这个库的功能就是“读取对方进程内存地址,将指向MessageBoxA的地址转换成指向MyMessageBoxA的”。 你高兴了把它的部分代码拷贝到你的代码中调通就行。
ssr奥利奥 2015-12-15
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
https://www.baidu.com/s?wd=detours&rsv_spt=1&rsv_iqid=0xbb1f641200001eb4&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_n=2&rsv_sug3=1
赵老师,我们的要求是不用这种现成的库函数,而是读取对方进程内存地址,将指向MessageBoxA的地址转换成指向MyMessageBoxA的。
ssr奥利奥 2015-12-15
  • 打赏
  • 举报
回复
引用 1 楼 fly_dragon_fly 的回复:
用一下detours好了
具体操作可以说下吗
一、简介   AheadLib 是用来生成一个特洛伊DLL的工具,用于分析DLL中的函数参数调用(比如记录Socket send了什么等等)、更改函数功能(随心所欲了:)、更改界面功能(比如在Hook里面生成一个按钮,截获事件等等)。 二、使用   1.用 AheadLib 打开要模拟的 DLL,生成一个 CPP 文件。   2.用 Visual Studio 6.0/.NET 建立一个 DLL 工程,把这个 CPP 文件加入到项目中。   3.使用 Release 方式编译,生成的 DLL 将和原来的 DLL 具有一模一样的导出函数,并且能顺利把这些函数转发到原来的函数中。   4.AheadLib 还可以生成 Hook 代码,用于截取当前进程的所有消息,这样就可以随心所欲地处理各种消息了 (修改第三方程序界面功能的好助手)。 三、备注   1.如果导出函数过多,在 Visual Studio 6.0 中,如果出现编译错误,请在项目属性关闭与编译头功能。   2.如果是 C++ 、C __stdcall、C __fastcall 的方式导出的话,生成的函数声明将会还原成原代码级别(可能需要修改才能编译,比如导出C++类的情况)。此时使用 __declspec(dllexport) 导出 ——不能指定导出序号。   3.如果是 NONAME 或者 C _CDECL 方式导出(比如 DEF 导出,大多数Windows DLL都是这种情况,比如WS2_32等等),则使用#pragma comment(linker, "/EXPORT:...)导出,且指定导出序号。   4.如果系统中没有 DbgHelp.dll,将无法识别 C++ 模式的导出。

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧