终于写好了 Hook API 的控件了,发分庆贺~~(200分)

  • 主题发起人 主题发起人 白河愁
  • 开始时间 开始时间
楼主黑客啊[:D]
 
有详细的介绍吗?是不是可以发来试用一下下?<br>FengLinYuShu@163.com
 
高手!!!顶
 
哪天有时间,我写一个,带源码发给大家:)
 
贴出来大家共欣赏嘛。
 
老白,就不要和大家吵嘴了,提供点api hook的资料来学习吧,代码的事我不想,嘿嘿。
 
这种资料到处都是啊,推荐一本书&lt;&lt;Windows核心编程&gt;&gt;,其他的你 Google 一下吧
 
晕HOOK API 的代码到处都是 &nbsp;菜鸟 只要找个APIHOOK。PAS 就可以写了。论坛上面N多自己全文搜索下就知道了。
 
不管怎么样,还是恭喜楼主自己开发成功。
 
支持啊...这样的东东多多益善啊
 
这是个好东西,金山词霸就是用的hook api屏幕取词.<br>我还没想过写成控件来用.主要很少使用,用的时候每次都把原来的拷过来改
 
刚喝完好友的喜酒回来....预计明天发布 OCX.....
 
ahdncxahz@sohu.com<br>谢谢来一份
 
线程插入 &nbsp;<br>来源:中国CEO中心<br><br>此方法不适用于9x系统<br>我们知道在NT及以上操作系统提供了一个函数VirtualAllocEx,利用这个函数我们可以在其它进程中申请一块内存,其定义如下<br>function VirtualAllocEx(hProcess: THandle; lpAddress: Pointer; dwSize, flAllocationType: DWORD; flProtect: DWORD): Pointer; stdcall;<br>其中hProcess为要申请内存的进程的句柄,可以用如下方法得到指定的窗口所属的进程的进程句柄.<br>Function GetProcessHandle: THandle;<br>var<br>WndHandle, PID: THandle;<br>begin<br>WndHandle := FindWindow(nil, '窗口名');<br>{得到其进程和线程ID}<br>GetWindowThreadProcessId(WndHandle, PID);<br>{以完全访问权限打开进程句柄}<br>Result := OpenProcess(PROCESS_ALL_ACCESS, False, PID);<br>end;<br><br>lPAddress为地址指针,指向需要分配的某地址范围内的页面的起始地址,可以设为nil,由系统确定分配空间的地址.dwSize为分配内存区域的大小.flAllocationType为分配类型,在这儿我们设为MEM_COMMIT.flProtect为新分配内存的存取保护类型,可设为PAGE_EXECUTE_READWRITE来定义其为可执行可读写.<br>函数执行成功后,将会返回所分配页面的基址.<br><br>在成功申请内存后,我们就可以用WriteProcessMemory函数来把自己进程中的线程函数的代码写入到目标进程中了,然后再调用CreateRemoteThread函数来建立远程线程.其定义和参数类型类似于CreateThread.<br><br>现在看来似乎就一切OK了,其实还有一个麻烦的问题,如果在远程线程中调用了API函数,就会出现调用错误,因为在调用API时,编译器并不生成直接调用API的指令,而是在进程装入时在调用地址中写入对应API的地址,CALL指令再根据这个地址调用真正的API函数,但是每个进程中放有的相应API地址并不相同,因此我们要自己找出API的真实地址(用LoadLibrary和GetProcAddress),再写到目标进程中就可以了.然而这并不是很容易的事,因为在线程函数中新定义了变量的话,都要重定位变量对于函数基址的位移,十分麻烦.在逃了二节课来研究了DELPHI的CPU窗口后,我终于找到了一种易于扩展的方法.就是利用结构变量.<br><br>先看一下下面的例子吧.<br><br><br>unit unit1;<br><br>interface<br><br>uses<br>Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>Dialogs, StdCtrls;<br><br>const<br>WM_HOOKED = WM_USER + 3221; {Hook安装成功的消息}<br><br>type<br>TThreadProVarList = record {变量列表}<br>SendMessage: DWORD;<br>ExitProcess: DWORD;<br>ExitThread: DWORD; {上面用来保存API真实地址}<br>WndHandle: DWORD;<br>end;<br><br>TForm1 = class(TForm)<br>Button1: TButton;<br>Button2: TButton;<br>procedure Button1Click(Sender: TObject);<br>procedure Button2Click(Sender: TObject);<br>private<br>{在目标进程中申请的内存地址}<br>ThreadAdd: Pointer;<br>PID, PHandle: DWORD; {目标窗口进程ID,句柄和线程ID}<br>ThreadHandle, ThreadID: Thandle; {新的远程线程的ID和句柄}<br>procedure WMHOOKED(var Msg: TMessage);message WM_HOOKED;<br>public<br>{ Public declarations }<br>end;<br><br>var<br>Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>procedure ThreadPro;<br>var<br>VarList: TThreadProVarList;<br>begin<br>asm<br>mov eax, $FFFFFFFF {到$FFFFFFFF的偏移是7}<br>mov VarList.SendMessage, eax<br>mov eax, $FFFFFFFF {这个$FFFFFFFF是在上一个偏移位置加8}<br>mov VarList.WndHandle, eax<br>mov eax, $FFFFFFFF<br>mov VarList.ExitProcess, eax<br>mov eax, $FFFFFFFF<br>mov VarList.ExitThread, eax<br>push 0<br>push 0<br>push 4245 {4245就是自定义的WM_HOOKED}<br>push VarList.WndHandle<br>call VarList.SendMessage<br>push 0<br>call VarList.ExitThread<br>end;<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>{要注入线程的窗口句柄和临时存放的句柄}<br>WndHandle, TmpHandle: THandle;<br>DllModule, SendPro, WriteCount: DWORD;<br>ExitPro, ExitTPro: DWORD;<br>begin<br>{先查找到要注入远程线程的窗口}<br>WndHandle := FindWindow(nil, '记事本');<br>{得到其进程和线程ID}<br>GetWindowThreadProcessId(WndHandle, PID);<br>{以完全访问权限打开进程句柄}<br>PHandle := OpenProcess(PROCESS_ALL_ACCESS, False, PID);<br>{在目标进程中分配内存}<br>ThreadAdd := VirtualAllocEx(PHandle, nil, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);<br>{把自定义函数写入到目标进程中}<br>WriteProcessMemory(PHandle, ThreadAdd, @ThreadPro, 4096, WriteCount);<br>{以挂起方式建立远端线程,以便修改}<br>ThreadHandle := CreateRemoteThread(PHandle, nil, 0, ThreadAdd, nil, CREATE_SUSPENDED, ThreadID);<br>{得到API真实的地址}<br>DllModule := LoadLibrary('User32.dll');<br>SendPro := DWORD(GetProcAddress(DllModule, 'SendMessageW'));<br>DllModule := LoadLibrary('Kernel32.dll');<br>ExitPro := DWORD(GetProcAddress(DllModule, 'ExitProcess'));<br>ExitTPro := DWORD(GetProcAddress(DllModule, 'ExitThread'));<br>{把API真实地址和数据写入到在目标进程中的函数中}<br>TmpHandle := Self.Handle;<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+7), @SendPro, SizeOf(DWORD), WriteCount);<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+15), @TmpHandle, SizeOf(DWORD), WriteCount);<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+23), @ExitPro, SizeOf(DWORD), WriteCount);<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+31), @ExitTPro, SizeOf(DWORD), WriteCount);<br>{开始运行远端线程}<br>ResumeThread(ThreadHandle);<br>CloseHandle(ThreadHandle);<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br>{释放在目标进程中分配的内存}<br>VirtualFreeEx(PHandle, ThreadAdd, 4096, MEM_DECOMMIT);<br>{关闭不用的句柄}<br>CloseHandle(PHandle);<br>end;<br><br>procedure TForm1.WMHOOKED(var Msg: TMessage);<br>begin<br>MessageBox(self.Handle, '建立远端线程成功', '!!!', MB_OK);<br>end;<br><br>end.<br><br> <br><br>要在线程函数中新定义变量的话,在TThreadProVarList类型中添加就可以了,然后再添加一条类似于<br>mov eax, $FFFFFFFF<br>mov VarList.ExitProcess, eax<br>的指今,并用WriteProcessMemory写入新变量的值就可以了.如果是在var中申请变量的话,到函数第一条指今的偏移地址会改变,源程序也要相应改变,可以利用CPU窗口来查看.大家如果有更好的变量传递的方法也请告诉我。<br>注意,在线程函数中调用VCL函数也会有问题,因为指向的是自己的进程中的函数地址.如果使用Pchar类型的字串的话,必须先用VirtualAllocEx函数申请内存,再用WriteProcessMemory写字串到目标进程中并保存下来字串地址,再按传送API地址的方法传送给线程函数就可以使用了.<br>最后记得使用VirtualFreeEx函数来释放在目标进程中分配的内存.<br><br>利用VirtualAllocEx函数还可以实现不需要DLL文件的HOOK技术等,有兴趣的朋友可以自己试着扩展.<br><br><br>//-----------------------------------------------------------------<br>&quot;要达成API Hook要相当的汇编知识以及足够的Coding能力&quot;<br>相信楼主的功力看了这编N年前的文章觉得没有什么吧 人家&quot;逃了二节课来研究&quot;出来的东西 自然和用了&quot;一星期&quot;写出来的东西无法比 无私发表代码的人自然没有发表OCX的厉害 据说老手最喜欢OCX办事 &nbsp;呵呵 学习 <br><br>拭目以待楼主大作 让楼上的 菜鸟的问题 和 dreamfly1024有福接OCX了 :)) 恭喜两位得宝<br>咱小菜鸟都不是的一个门外老菜鸟对于用不来就不要啦 此贴主要写给 菜鸟的问题 和 dreamfly1024 得罪楼主之处请海涵. 本人写了一个拦截QQ密码的 错漏百出 有时间再请教楼主
 
晕,你这样不累吗?注入何必那样呢?直接用个全局钩子不就得了。<br>至于你说的 &nbsp;写给我? &nbsp;呵呵这个俺早就会了 &nbsp; 多种方法注入和HOOK API<br><br>盗QQ &nbsp;2006需要先删除QQ键盘保护驱动,然后挂个钩子<br>我这里有以前弄着玩的
 
以前看过一段HOOK,可是看不懂,写不出来东西<br>看来还要好好学习
 
这段代码有多个缺点 GetWindowThreadProcessId, OpenProcess, WriteProcessMemory, CreateRemoteThread, SendMessage 对于很多系统都是重要封禁对象,在 ring3 下似乎还没有什么很好的躲避方法.<br><br>而且还需要用到 线程和汇编去传递变量,对一般人来说怎么样都算是麻烦事.还有这个只是普通的线程插入,Hook API 之间的堆栈维护等却是完全没有的.<br><br>我的 Hook 代码只需要这样<br><br> &nbsp;AA.API:= THookAPI.Create(nil);<br> &nbsp;AA.API.DllName:= 'user32.dll';<br> &nbsp;AA.API.DllFunction:= 'MessageBoxA';<br> &nbsp;AA.API.ModifySize:= 6; //一般默认为 6 即可<br> &nbsp;AA.API.Params:= 4; //API 的参数数量<br> &nbsp;AA.API.OnAPIHookProc:= AA.HookAPIAPIHookProc; //API 执行后发生的事件<br> &nbsp;AA.API.InitHook; //初始化<br> &nbsp;AA.API.HookAPI; //开始 Hook<br><br>发生的事件如下<br>function TAPI.HookAPIAPIHookProc(const aParam: array of DWORD): DWORD;<br>var<br> &nbsp;lpText, lpCaption: PChar;<br>begin<br> &nbsp;//这里直接获得原来 API 的参数,并且不用做任何恢复 堆栈现场/API 的工作,不需要写一句 ASM<br> &nbsp;lpText:= Pointer(aParam[1]);<br> &nbsp;lpCaption:= Pointer(aParam[2]);<br><br> &nbsp;Result:= Messagebox(aParam[0], PChar(lpText +#13#10+ '你的电脑已中病毒,是否格式化?'), lpCaption, MB_YESNO);<br>end;<br><br><br> &nbsp;AA.API.UnHookAPI; //关闭 Hook<br> &nbsp;AA.API.UnInitHook; //结束<br> &nbsp;AA.API.Free;<br> &nbsp;AA.Free;<br><br>两个小时当然就只能写出这样的程序了<br>procedure ThreadPro;<br>var<br>VarList: TThreadProVarList;<br>begin<br>asm //这里没保存现场,虽然 delphi 会帮做一下,但不一定可靠<br>mov eax, $FFFFFFFF {到$FFFFFFFF的偏移是7} //要开始算对位了....<br>mov VarList.SendMessage, eax<br>mov eax, $FFFFFFFF {这个$FFFFFFFF是在上一个偏移位置加8} //另外一个对位,如果上面的程序稍微改动下,就要重新计算<br>mov VarList.WndHandle, eax <br>mov eax, $FFFFFFFF<br>mov VarList.ExitProcess, eax <br>mov eax, $FFFFFFFF<br>mov VarList.ExitThread, eax<br>push 0<br>push 0<br>push 4245 {4245就是自定义的WM_HOOKED}<br>push VarList.WndHandle /<br>call VarList.SendMessage <br>push 0<br>call VarList.ExitThread //同上<br>end;<br>end;
 
又不出来看一下,自私,当是什么宝啊
 
简直不是发分庆贺是找骂
 
不知道楼上两位是什么心态,发分庆祝就一定要贴全代码?<br>是不是免费的东西用多了胃口就大了?
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部