不完美逆向320块的apihook教程

一笑拔剑 2009-06-12 04:28:45
给分的内容在后面,高手可以跳过第一段,直接看第2段的代码!能提供帮助的绝对不会吝啬分数的!

不完美逆向320块的apihook教程
好把,他的是教程,俺这不是,只是写着玩的简单的逆向烂文。希望各位客官不要拍砖。
要说起来逆向这个程序的原因呢,其实也很简单,前段时间在天空下载软件,无意中发现了一个软件。自称是API拦截技术教程,还开价320元。apihook的技术在windows核心技术里讲了很多,居然还有人卖这么贵,我就对他来了点兴趣。程序的简介是这样的。
对于程序员来讲,API拦截技术是一种重要的基础技术。这项技能为编写某些工具软件提供了可能,并可以大大提高我们对第三方应用程序的控制能力。不过,目前 API 拦截的技术资料往往局限于原理方面的论述,对于如何具体地编译一个 API 拦截程序却守口如瓶。毕竟,对于程序员来讲,当初学习这项技能花费了不少心血,如果让他们无偿地奉献出来,恐怕不太现实;另外的一个因素就是竞争,多一个人学会这项技能,就多一份竞争。我在掌握这项技能的时候,就走了不少弯路,如果当初有一份详细的资料,这些不必要的弯路是完全可以避免。而这正是我编写这份技术资料的目的。
本程序是一个示例程序,用以演示如何拦截 API 调用。开始拦截 CreateProcess之后,当用户通过资源管理器运行程序时,就会弹出一个对话框提示用户运行了什么程序。停止拦截之后,用户运行程序时则不会弹出对话框。
随本程序附带的教程是未注册版本,如果您需要详细的资料,请通过网上商城进行注册。注册费用为 320 元人民币。最终价格请以网上商城的价格为准。
这就引起了我的好奇,难道这个软件用了什么牛x的新技术?居然这么值钱!那得看看,于是就把该软件下载下来研究了研究。谁知道,他所用的技术不但一点创新都没有,还有着很大的局限性。于是就有了这篇文章,还希望高手不要见笑。
这个程序的原版大家自己找,名字就叫做API拦截教程。启动该程序后,按下拦截createprocess的按钮后,运行任何程序都会弹出运行程序的路径。稍微了解apihook的都了解,通常ring3下hookapi的办法有三种,一是修改程序的iat表,使api调用跳向自己的函数而不是转向api入口。二是修改api入口的机器码。三是用创建远线程CreateRemoteThread的办法来完成。那么这个教程究竟用了什么先进手法呢?
先运行一次,按下按钮后,果然explorer弹出了程序的路径。此时,你如果使用icesword类的可以查看程序模块的程序查看explorer的模块,你就会发现explorer里面多了个InterceptDll.dll的模块,当我们卸载了这个dll后,这个拦截的效果就没有了。看来这个程序的核心不是那个启动的程序,而是这个dll。现在让我们看看这个InterceptDll.dll到底做了什么。
先使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件
DUMPBIN InterceptDll.dll /EXPROTS /OUT:InterceptDll.def
ordinal hint RVA name

1 0 00001230 InstallHook
2 1 00001270 UninstallHook
只有两个导出函数,看名字就知道,一个是安装钩子,一个卸载钩子。我们调用看看 ,结果连参数都不用,只要调用InstallHook就可以把InterceptDll.dll插入explorer,用UninstallHook就可以卸载钩子。看来我们不用分析他的exe文件了,因为有用的东西就在这个dll里。那么如何分析这个dll这么工作的呢?直接用ida看静态代码,可以看见dll里有vivirtualalloc,setwindowshookexa等钩子函数。但是,里面乜嘢CreateRemoteThread这个函数,那么基本可以排除了第三种方法了。修改iat或者字节数的可能性比较大一些。那么具体究竟是用了什么手段,又是怎么实现的呢?光静态看源代码看出来,我可没那种本事。如果说要实时调试explorer又非常的麻烦,那么怎么办呢?其实办法很简单啦,只要自己修改一个exe文件名让他跟explorer同名就可以了。这家伙可不管你是真李逵还是假李鬼,统统都插!我先写了个很简单的exe程序,只有一个按钮直接掉用createprocess启动notepad的小程序,然后改名为explorer。运行后让程序拦截,果然再用icesword看模块,那个InterceptDll.dll偷偷的钻进了我写的这个程序。
好,现在动手钻进InterceptDll.dll的内部,看看他到底干了什么!我用的是olldbg,其实windbg也可以,我用od习惯了。先附加到我自己写的这个小explorer程序,然后在createprocess下断点,按下启动notepad的按钮,断下以后,一步一步跟踪。当进入到原先createprocess的领空的时候,入口变了
7C802332 >- E9 B9ED7F93 jmp 100010F0
7C802337 6A 00 push 0

变成了跳向100010F0,运行了这个跳转,就进入了dll的程序代码段。具体汇编代码如下。
100010F1 8BEC mov ebp, esp
100010F3 6A FF push -1
100010F5 68 50710010 push 10007150
100010FA 68 7C220010 push 1000227C
100010FF 64:A1 00000000 mov eax, dword ptr fs:[0]
10001105 50 push eax
10001106 64:8925 0000000>mov dword ptr fs:[0], esp
1000110D 83EC 0C sub esp, 0C
10001110 53 push ebx
10001111 56 push esi
10001112 57 push edi
10001113 33C0 xor eax, eax
10001115 8945 E4 mov dword ptr [ebp-1C], eax
10001118 8945 FC mov dword ptr [ebp-4], eax
1000111B 50 push eax
1000111C 68 44710010 push 10007144 ; ASCII "鎎*b"
10001121 8B75 0C mov esi, dword ptr [ebp+C]
10001124 56 push esi
10001125 50 push eax
10001126 FF15 FC700010 call dword ptr [100070FC] ; USER32.MessageBoxW
1000112C 8B45 2C mov eax, dword ptr [ebp+2C]
1000112F 50 push eax
10001130 8B4D 28 mov ecx, dword ptr [ebp+28]
10001133 51 push ecx
10001134 8B55 24 mov edx, dword ptr [ebp+24]
10001137 52 push edx
10001138 8B45 20 mov eax, dword ptr [ebp+20]
1000113B 50 push eax
1000113C 8B4D 1C mov ecx, dword ptr [ebp+1C]
1000113F 51 push ecx
10001140 8B55 18 mov edx, dword ptr [ebp+18]
10001143 52 push edx
10001144 8B45 14 mov eax, dword ptr [ebp+14]
10001147 50 push eax
10001148 8B4D 10 mov ecx, dword ptr [ebp+10]
1000114B 51 push ecx
1000114C 56 push esi
1000114D 8B55 08 mov edx, dword ptr [ebp+8]
10001150 52 push edx
10001151 E8 7AFFFFFF call 100010D0
当运行到 call 100010D0 时开始跳回原领空
call 100010D0里面的实际代码是这样的。
100010D0 8BFF mov edi, edi
100010D2 55 push ebp
100010D3 8BEC mov ebp, esp
100010D5 - E9 5D12806C jmp kernel32.7C802337
而 kernel32.7C802337处
100010D0 8BFF mov edi, edi
100010D2 55 push ebp
100010D3 8BEC mov ebp, esp
正是原本createprocess代码接下来的一段
到这里,这个dll的hook功能就真相大白了,他完全没有使用什么新技术来完成hook。照样是修改api函数的头5个字节,然后跳转到自己的函数,之后再构造一个类似的头,最后跳回原来的api领空继续运行。这个完全就是windows核心编程里的代码的照抄,就这抄一下就要人320元,是在有点太黑了吧!
更为重要的是,apihook中这样的hook有很大的缺陷,为什么这么说呢?我们可以看见他是将入口修改为 jmp 100010F0
7C802332 >- E9 B9ED7F93 jmp 100010F0
我们知道一般的api函数头部是不会出现这样的远距离的jmp的,所以只要检测api的函数头一个字节是否e9就可以很轻松的检测出api是否被hook住了。还有一个问题就是,如果我们的目的并不停止于,只是在api函数处理之前修改某些入口函数或者做些处理,而是整个重新处理而不回到系统的api处理处,这个流程也不符合我们的要求。
不过没有关系,既然现在我们已经知道了这个dll工作的大至流程,我们也可以自己写一个拦截createprocess的dll了,而我们把这个程序改进一下,使他成为一个全局的钩子,而且我们可以选择程序的开启,在程序开启以前弹出一个msgbox,上面有是和否的按钮,你按下是程序就不能启动,而按下否程序就照常启动,而弹出的按钮里不但有这个程序的路径,还有启动这个程序的路径。怎么样,比他的还要高级一些吧。
...全文
334 21 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
一笑拔剑 2009-06-14
  • 打赏
  • 举报
回复
自己解决了

直接写4个字节

跟下源代码就知道的

dword直接赋值eax不行
DavidHsing 2009-06-13
  • 打赏
  • 举报
回复
像你说的 A 和 W 这种情况,一般来讲,是需要 hook 两个 API,A 和 W 版本的都要处理。
因为可能有的程序编译是多字节,有的使用 Unicode,而作为全局钩子,要考虑到这两种情况,所以都需要处理。
虽然两个的函数体逻辑可能差不多,甚至一样。
一笑拔剑 2009-06-13
  • 打赏
  • 举报
回复
分不够还是怎么的

不够可以再加
zoulie 2009-06-13
  • 打赏
  • 举报
回复
现在应用层API HOOK满大街都是,连SSDT HOOK,INLINE HOOK 都满地爬了。。。。
逆向的话去去kanxue,debugman。。。那里牛多
一笑拔剑 2009-06-13
  • 打赏
  • 举报
回复
主要就这里不行
DWORD lpNewApi = (DWORD)MyCreateProcessW;


hack.b = lpNewApi;
因为dword值在vc下是32位的
而mov eax,offset MyCreateProcessW
eax里的值是16位的
不知道vc如何转换,

希望高手帮忙
一笑拔剑 2009-06-13
  • 打赏
  • 举报
回复
很遗憾

这个代码不对,

因为dword值是32位的

这样的时候插入到代码里就全部错误了

我看了看其他代码

只能用byte[4]然后把eax倒序插入才可以

但是我用了这个办法后还是不对,还是希望有高手帮忙看一下
chehw 2009-06-13
  • 打赏
  • 举报
回复
对于问题1:可以使用FlushInstructionCache直接执行机器码
OrochiZ 2009-06-13
  • 打赏
  • 举报
回复
DWORD在哪都是32位的吧
EAX也是32位的啊
干吗要转换?
DavidHsing 2009-06-12
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 aspower_ 的回复:]
是这样的,由于你钩上了createprocessw以后
你重新回调api的时候,默认调用的是createprocessa,这样的话就会出现参数错误的问题了
而去掉用createprocessw的时候,vc会显示 LPSTARTUPINFO 的格式错误
我用asm不用考虑这个直接用dword就ok了,vc就不行,主要是这个方面的问题!
[/Quote]

明白了,原来绕了个圈,就是要调原函数啊。
这个我用 IAT 的方式很好处理,jmp 的没仔细研究过。
用户 昵称 2009-06-12
  • 打赏
  • 举报
回复
只学过dos汇编,windows下的只能看懂。
一笑拔剑 2009-06-12
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 killbug2004 的回复:]
就是改函数头
mov eax, address
jmp eax

有点问题,改改吧,

C/C++ code#define UNICODE
#include <windows.h>
#pragma comment(lib,"kernel32.lib")
#pragma comment(lib, "user32.lib")

typedef struct {
BYTE a;
DWORD b;
BYTE c;
BYTE d;
} HACK;


PROC m_pfnOrig;
//BYTE m_btNewBytes[8];
HACK hack;
BYTE m_btOldBytes[8];
HMODULE m_hMod;
bool shu…
[/Quote]
3q 测试可用就回来加分
一笑拔剑 2009-06-12
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 DavidHsing 的回复:]
Hook 的函数是要和原函数的参数一模一样,你说的你不了解 LPSTARTUPINFO 的宽字符格式,
MSDN 里面都有啊,不知道你说的格式是什么意思?里面的 LPTSTR 么?


C/C++ code
typedef struct _STARTUPINFO {
DWORD cb;
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFil…
[/Quote]
是这样的,由于你钩上了createprocessw以后
你重新回调api的时候,默认调用的是createprocessa,这样的话就会出现参数错误的问题了
而去掉用createprocessw的时候,vc会显示 LPSTARTUPINFO 的格式错误
我用asm不用考虑这个直接用dword就ok了,vc就不行,主要是这个方面的问题!
killbug2004 2009-06-12
  • 打赏
  • 举报
回复
就是改函数头
mov eax, address
jmp eax

有点问题,改改吧,
#define UNICODE
#include <windows.h>
#pragma comment(lib,"kernel32.lib")
#pragma comment(lib, "user32.lib")

typedef struct {
BYTE a;
DWORD b;
BYTE c;
BYTE d;
} HACK;


PROC m_pfnOrig;
//BYTE m_btNewBytes[8];
HACK hack;
BYTE m_btOldBytes[8];
HMODULE m_hMod;
bool shutok;
HHOOK hHook;
HINSTANCE hInstance;
BOOL Rehook()
{
// 修改原API函数执行代码的前8个字节,使它跳向我们的函数
if(m_pfnOrig != NULL)
{
DWORD dwOldProtect;
MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery( m_pfnOrig, &mbi, sizeof(mbi) );
::VirtualProtect(m_pfnOrig, 8, PAGE_READWRITE, &dwOldProtect);

// 写入新的执行代码
::WriteProcessMemory(::GetCurrentProcess(), (void *)m_pfnOrig,
&hack, sizeof(HACK), NULL);

::VirtualProtect(m_pfnOrig, 8, mbi.Protect, 0);
return true;
}
return FALSE;
}



BOOL WriteBack()
{
if(m_pfnOrig != NULL)
{
DWORD dwOldProtect;
MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery(m_pfnOrig, &mbi, sizeof(mbi));
::VirtualProtect(m_pfnOrig, 8, PAGE_READWRITE, &dwOldProtect);

// 写入原来的执行代码
::WriteProcessMemory(::GetCurrentProcess(), (void *)m_pfnOrig,
m_btOldBytes, sizeof(DWORD)*2, NULL);

::VirtualProtect(m_pfnOrig, 8, mbi.Protect, 0);
return true;
}
return false;
}


BOOL _declspec(naked) MyCreateProcessW(
LPCWSTR lpApplicationName, // pointer to name of executable module
LPWSTR lpCommandLine, // pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security attributes
BOOL bInheritHandles, // handle inheritance flag
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // pointer to new environment block
LPCWSTR lpCurrentDirectory, // pointer to current directory name
LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION
)
{
WriteBack();

if (::MessageBoxW(NULL, GetCommandLineW(), lpApplicationName, 4) != 7)
{
BOOL shutok = ::CreateProcess(
lpApplicationName, // pointer to name of executable module
lpCommandLine, // pointer to command line string
lpProcessAttributes, // pointer to process security attributes
lpThreadAttributes, // pointer to thread security attributes
bInheritHandles, // handle inheritance flag
CREATE_SUSPENDED, // creation flags
lpEnvironment, // pointer to new environment block
lpCurrentDirectory, // pointer to current directory name
lpStartupInfo, // pointer to STARTUPINFO
lpProcessInformation // pointer to PROCESS_INFORMATION
);

//HANDLE hProcess1=ProcessInfo.hProcess;
//RemoteLoadLibrary(hProcess1,"hook.dll");
//ResumeThread(ProcessInfo.hThread);
}

Rehook();

__asm
{
push shutok
pop eax
ret 4
}
}


BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
//BYTE btNewBytes[8]={0xB8,0xE0,0x18,0x00,0x10,0xFF,0xE0,0x00};
//memcpy(m_btNewBytes,btNewBytes,8);



if (ul_reason_for_call == DLL_PROCESS_ATTACH) //当DLL加载时产生此事件
{

hInstance = (HINSTANCE)hModule;

m_hMod = ::LoadLibrary(TEXT("kernel32.dll")); //取API地址


if (m_hMod == NULL)

{
m_pfnOrig=NULL;
return true;
}

m_pfnOrig = ::GetProcAddress(m_hMod, "CreateProcessW");

if (m_pfnOrig != NULL)

{
ZeroMemory(&hack, sizeof(HACK));

DWORD lpNewApi = (DWORD)MyCreateProcessW;

hack.a = 0xB8;
hack.b = lpNewApi;
hack.c = 0xFF;
hack.d = 0xE0;

DWORD oldProc;
MEMORY_BASIC_INFORMATION mbi;

::VirtualQuery (m_pfnOrig,&mbi,sizeof(mbi));
::VirtualProtect( m_pfnOrig,8,PAGE_READWRITE,&oldProc);
memcpy(m_btOldBytes,m_pfnOrig,8);
::WriteProcessMemory(::GetCurrentProcess(), (void*)m_pfnOrig, &hack, sizeof(HACK), NULL);
::VirtualProtect( m_pfnOrig,8,mbi.Protect ,0);
return true;
}
}
if (ul_reason_for_call == DLL_PROCESS_DETACH) //当DLL加载时产生此事件
{
WriteBack();
return TRUE;
}

return TRUE;
}


LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam,LPARAM lParam)
{
return (LRESULT)CallNextHookEx(hHook, nCode, wParam, lParam);
}

void __declspec(dllexport) InstallHook()
{
hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, hInstance, NULL);
}

void __declspec(dllexport) UninstallHook()
{
UnhookWindowsHookEx(hHook);
WriteBack();
}
DavidHsing 2009-06-12
  • 打赏
  • 举报
回复
Hook 的函数是要和原函数的参数一模一样,你说的你不了解 LPSTARTUPINFO 的宽字符格式,
MSDN 里面都有啊,不知道你说的格式是什么意思?里面的 LPTSTR 么?


typedef struct _STARTUPINFO {
DWORD cb;
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFO, *LPSTARTUPINFO;
DavidHsing 2009-06-12
  • 打赏
  • 举报
回复
嗯,可惜汇编我早就不会编了,我一般用 API hook 也是用 IAT,不是修改的 jmp 指令。
这样虽然可能漏掉(有的函数不一定会在输入表里面),
但是由于不需要每次都修改和恢复 jmp,所以稳定性和效率上有很大提高。

我在自己测试的时候,也借用了第三方工具来辅助,比如 APIMonitor。
我想 lz 说的这个软件这个差不多,不过这个是老外编写的。
http://www.apimonitor.com/

我是自己参照了 n 多 CodeProject 上的文章自己编写的 API hook 类,不是采用的微软的 Detours。
没想到这样的小东东居然还有人拿出来卖 320,真是... 没天理了
要我自己做我也能做出来,全面的 hook 阶段我之前都已经写好了,并且测试没有问题
(可以看 http://blog.csdn.net/DavidHsing/archive/2009/05/27/4219226.aspx)
要接着做的话,只需要弄个 dll 做成全局钩子,注入到所有进程里面去。

我看你第二段写的,是采用修改 jmp 指令的办法掉到我们自己的 API 函数体。
由于我的方案不是这个,所以我对于这种方案也就没有仔细的 coding 和调试。
给你两篇文章,希望对你有所帮助;

API hooking revealed
http://www.codeproject.com/KB/system/hooksys.aspx

Hooking the native API and controlling process creation on a system-wide basis
http://www.codeproject.com/KB/system/soviet_protector.aspx
一笑拔剑 2009-06-12
  • 打赏
  • 举报
回复
难道没有高手帮忙看一下么?

如果嫌分不够

可以再加
sunm42000 2009-06-12
  • 打赏
  • 举报
回复
好深奥。。。mark
chinezwq 2009-06-12
  • 打赏
  • 举报
回复
学习一下
一笑拔剑 2009-06-12
  • 打赏
  • 举报
回复
源代码可以在这里下载
http://download.csdn.net/source/1402519
一笑拔剑 2009-06-12
  • 打赏
  • 举报
回复
(asm代码改自nohack的代码)
ASM的代码如下:


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
; 原代码编写 by hacker0058
; aspower 稍做修改
汇编(MASM):最简单的HOOK API ;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;


.486
.model flat,stdcall
option casemap:none

include windows.inc
include kernel32.inc
include winmm.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
include psapi.inc
includelib psapi.lib
;include winmm.inc
;includelib winmm.lib


HOOKAPI struct
a byte ?
PMyapi DWORD ?
d BYTE ?
e BYTE ?
HOOKAPI ends


;子程序声明
WriteApi proto :DWORD ,:DWORD,:DWORD,:DWORD
MyAPI proto :DWORD ,:DWORD ,:DWORD ,:DWORD ,:DWORD ,:DWORD ,:DWORD ,:DWORD ,:DWORD ,:DWORD
GetApi proto :DWORD,:DWORD


;已初始化数据
.data
hInstance dd 0
WProcess dd 0
hacker HOOKAPI <>
CommandLine LPSTR ?
str1 LPSTR ?


Papi1 DWORD ?
Myapi1 DWORD ?
ApiBak1 db 10 dup(?)

DllName1 db "kernel32.dll",0
ApiName1 db "CreateProcessW",0



;未初始化数据

.data?
hHook dd ?
hWnd dd ?

;程序代码段

.code


;****************************************************************

;DLL入口点

DllEntry proc hInst:HINSTANCE, reason:DWORD, reserved1:DWORD


.if reason==DLL_PROCESS_ATTACH ;当DLL加载时产生此事件
push hInst
pop hInstance

invoke GetCommandLine
mov CommandLine,eax ;取程序命令行

;初始化

mov hacker.a,0B8h ;mov eax,
;mov hacker.d PMyapi ;0x000000
mov hacker.d,0FFh ;jmp
mov hacker.e, 0E0h ;eax

invoke GetCurrentProcess ;取进程伪句柄

mov WProcess ,eax

invoke GetApi,addr DllName1,addr ApiName1 ;取API地址

mov Papi1,eax ;保存API地址

invoke ReadProcessMemory,WProcess,Papi1,addr ApiBak1,8,NULL ;备份原API的前8字节

mov hacker.PMyapi,offset MyAPI ;0x000010 ;要替代API的函数地址

invoke WriteApi,WProcess,Papi1, addr hacker ,size HOOKAPI ;HOOK API

.endif

.if reason==DLL_PROCESS_DETACH

invoke WriteApi,WProcess,Papi1, addr ApiBak1 ,8 ;还原API

.endif

mov eax,TRUE
ret
DllEntry Endp

;****************************************************************


GetMsgProc proc nCode:DWORD,wParam:DWORD,lParam:DWORD
invoke CallNextHookEx,hHook,nCode,wParam,lParam
mov eax,TRUE

ret
GetMsgProc endp

;****************************************************************


InstallHook proc



invoke SetWindowsHookEx,WH_GETMESSAGE,addr GetMsgProc,hInstance,NULL
mov hHook,eax
ret
InstallHook endp

UninstallHook proc


invoke UnhookWindowsHookEx,hHook
invoke WriteApi,WProcess,Papi1, addr ApiBak1 ,8
ret
UninstallHook endp


;*****************************************************************

GetApi proc DllNameAddress:DWORD,ApiNameAddress:DWORD

invoke GetModuleHandle,DllNameAddress ;取DLL模块句柄

.if eax==NULL

invoke LoadLibrary ,DllNameAddress ;加载DLL

.endif

invoke GetProcAddress,eax,ApiNameAddress ;取API地址


mov eax,eax

ret

GetApi endp


;*********************************下面是核心部分*****************

WriteApi proc Process:DWORD ,Papi:DWORD,Ptype:DWORD,Psize:DWORD

LOCAL mbi:MEMORY_BASIC_INFORMATION
LOCAL msize:DWORD


;返回页面虚拟信息
invoke VirtualQueryEx,Process, Papi,addr mbi,SIZEOF MEMORY_BASIC_INFORMATION

;修改为可读写模式

invoke VirtualProtectEx,Process, mbi.BaseAddress,8h,PAGE_EXECUTE_READWRITE,addr mbi.Protect

;开始写内存

invoke WriteProcessMemory,Process, Papi, Ptype,Psize ,NULL

PUSH eax

;改回只读模式

invoke VirtualProtectEx,Process,mbi.BaseAddress,8h,PAGE_EXECUTE_READ,addr mbi.Protect
pop eax





ret

WriteApi endp

;*******************************************************************


;替代的API,参数要和原来一样

MyAPI proc lp1:DWORD ,lp2:DWORD,lp3:DWORD,lp4:DWORD,lp5:DWORD,lp6:DWORD,lp7:DWORD,lp8:DWORD,lp9:DWORD,lp10:DWORD,

mov eax,CommandLine
;mov CommandLine,eax
invoke WideCharToMultiByte,CP_ACP, 0, lp2, 128, addr str1, 128,NULL,NULL

;如果选择否
invoke MessageBoxEx, NULL,addr str1, CommandLine, 4,NULL


.if eax==7
invoke WriteApi,WProcess,Papi1, addr ApiBak1 ,8 ;先还原API
invoke CreateProcessW,lp1,lp2,lp3,lp4,lp5,lp6,lp7,lp8,lp9,lp10
PUSH eax
invoke WriteApi,WProcess,Papi1, addr hacker ,sizeof HOOKAPI ;调用完后再改回来



pop eax
ret

.endif

mov eax,0
ret

MyAPI endp

;*******************************************************************

End DllEntry
加载更多回复(1)

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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