|
Hook And Inject 系列教程 7.12 update
(不过现在问题也不大,用9x的人已经很少拉。)。唉,我现在还在瘟酒吧上混 |
|
[求助]请教:在VC里我调用外部程序的DLL时,参数传递出现错误???
语法类型检查不过关,我忘了你是使用C++的(C++的语法检查比较严格),上面的源码我用C是编译成功的。在C++里就要修改修改了。改成下面的就应该没问题了。 unsigned int temp; HANDLE hLibrary; FARPROC lpFunc; typedef int (__stdcall *MyFunc)(int temp); //定义一个自己的函数指针 MyFunc _MyFunc; //声明一个自定义函数指针 hLibrary=LoadLibrary("test.dll"); lpFunc=GetProcAddress(hLibrary,"addtest"); if(lpFunc != NULL) { temp=0x12345678; _MyFunc = (MyFunc)lpFunc; //将函数指针强制转成自己的函数定义 temp = _MyFunc(temp); //函数调用 // temp=lpFunc(temp); //就是这里编译通不过,如果把temp去掉就OK了,但是这样的话DLL里的参数就不对了 FreeLibrary(hLibrary); } else { Application->MessageBoxA("调用API失败?","错误",0); } //test.dll里的addtest函数的原形是 int addtest(int temp) |
|
[求助]请教:在VC里我调用外部程序的DLL时,参数传递出现错误???
改成这样大概就可以了。 unsigned int temp; HANDLE hLibrary; FARPROC lpFunc; int (*MyFunc)(int temp); hLibrary=LoadLibrary("test.dll"); lpFunc=GetProcAddress(hLibrary,"addtest"); if(lpFunc != NULL) { temp=0x12345678; 这里改成这样。 MyFunc = lpFunc; temp = (*MyFunc)(temp); // temp=lpFunc(temp); //就是这里编译通不过,如果把temp去掉就OK了,但是这样的话DLL里的参数就不对了 FreeLibrary(hLibrary); } else { Application->MessageBoxA("调用API失败?","错误",0); } //test.dll里的addtest函数的原形是 int addtest(int temp) |
|
微软的应试题完整版(附答案) 选择自 jswqg 的 Blo
呵呵,彼此彼此。 不过我的代码短一些,执行得更快一点。 |
|
微软的应试题完整版(附答案) 选择自 jswqg 的 Blo
我上面说的意思是: 比如我先倒两桶3公斤的水到5公斤的水桶里,这时在3公斤桶里就会剩下1公斤的水,5公斤桶里就有5公斤水,将5公斤水倒掉,放入3公斤里面的剩下的1公斤水到5公斤水桶里,再倒上一桶3公斤的水,合起来就是4公斤水了。 |
|
微软的应试题完整版(附答案) 选择自 jswqg 的 Blo
随便看了一眼,第一题的第3小节很简单: mov edx,3 mov eax,edx add eax,eax sub eax,5 add edx,eax |
|
[求助]关于代码自检测的编写。
或用硬件断点试试。 |
|
请教一下 Nowell 关于Delphi 代码的
其余上面我修改的消息代码在Delphi中就是OnEdit1Change事件 |
|
请教一下 Nowell 关于Delphi 代码的
那我上面给的应该是可以的。EN_CHANGE消息是Edit的消息,表示当Edit的本文更新后将会发送给窗口的消息,只要截获这个消息就可以监视Edit的本文更新了。 IDE_STARTBASE: if (wParam shr 16) = EN_CHANGE then IsFixInput(IDE_STARTBASE); |
|
请教一下 Nowell 关于Delphi 代码的
呵呵,我又看了一下你的程序,还是不太明白你的意思,我看见你上面的程序不是已经实现了Edit不断的检测输入了吗? IDE_STARTBASE : IsFixInput(IDE_STARTBASE); IDE_STARTEND : IsFixInput(IDE_STARTEND); IDE_CODEBASE : IsFixInput(IDE_CODEBASE); |
|
请教一下 Nowell 关于Delphi 代码的
function DlgProc( Wnd: hWnd; Msg:Cardinal ;wParam: wParam; lParam: LongInt Boolean; stdcall; var STARTBASE,STARTEND,CodeBase: TBuffer; hmainico: DWORD; whoid : WORD; begin Case Msg of WM_CLOSE: begin EndDialog(Wnd,0); Result := True; Exit; end; WM_INITDIALOG: begin SetDlgItemText(Wnd, IDE_CODEBASE, PChar( '00401000' ) ); hmainico:=LoadIcon(g_dllhmod, PChar(MYICO)); SendMessage(Wnd,WM_SETICON, ICON_SMALL, hmainico); Result := True; Exit; end; WM_COMMAND: begin whoid:=wParam; Case whoid of //在这里加一句这个就可以实时监视Edit的文本更新了 IDE_STARTBASE: if (wParam shr 16) = EN_CHANGE then IsFixInput(IDE_STARTBASE); IDE_STARTBASE : IsFixInput(IDE_STARTBASE); IDE_STARTEND : IsFixInput(IDE_STARTEND); IDE_CODEBASE : IsFixInput(IDE_CODEBASE); IDB_DONE: begin GetDlgItemText(Wnd, IDE_STARTBASE, @STARTBASE, 256 ); STARTBASE := GetCheck(STARTBASE); SetDlgItemText(Wnd, IDE_STARTBASE , @STARTBASE); GetDlgItemText(Wnd, IDE_STARTEND, @STARTEND, 256 ); STARTEND := GetCheck(STARTEND); SetDlgItemText(Wnd, IDE_STARTEND, @STARTEND ); GetDlgItemText(Wnd, IDE_CODEBASE, @CodeBase, 256 ); CodeBase := GetCheck(CodeBase); SetDlgItemText(Wnd, IDE_CODEBASE, @CodeBase ); Result := True ; Exit; end; IDB_CANCEL: begin SendMessage(Wnd,WM_CLOSE, 0, 0); Result := True ; Exit; {------------<Cancel被按下,退出>} end; end; // end case wm_cmd end; // end wm_cmd end; // end Case msg Result := False; end; |
|
求脱DLL壳(ASPACK2.12)教程
to ZERO 脱Aspack的Dll壳看这一篇文章: http://bbs.pediy.com/showthread.php?s=&threadid=1561 to chzhannet ESP定律看这一篇不错。 [转贴]Lenus兄弟写的寻找真正的入口(OEP)--广义ESP定律 作者:Lenus FROM: poptown.gamewan.com/bbs E-MAIL:meila2003@163.com 1.前言 在论坛上看到很多朋友,不知道什么是ESP定律,ESP的适用范围是什么,ESP定律的原理是什么,如何使用ESP定律?看到了我在“”调查结果发现,大家对ESP定律很感兴趣,当然因为实在是太好用了,现在我就来告诉大家什么是ESP定律,它的原理是什么! BTW:在看完了手动脱壳入门十八篇了以后,再看这篇文章也许会对你更有帮助! 在下面地址下载: http://www.jetdown.com/down/down.asp?id=37350&no=1 2.准备知识 在我们开始讨论ESP定律之前,我先给你讲解一下一些简单的汇编知识。 1.call 这个命令是访问子程序的一个汇编基本指令。也许你说,这个我早就知道了!别急请继续看完。 call真正的意义是什么呢?我们可以这样来理解:1.向堆栈中压入下一行程序的地址;2.JMP到call的子程序地址处。例如: 00401029 . E8 DA240A00 call 004A3508 0040102E . 5A pop edx 在执行了00401029以后,程序会将0040102E压入堆栈,然后JMP到004A3508地址处! 2.RET 与call对应的就是RET了。对于RET我们可以这样来理解:1.将当前的ESP中指向的地址出栈;2.JMP到这个地址。 这个就完成了一次调用子程序的过程。在这里关键的地方是:如果我们要返回父程序,则当我们在堆栈中进行堆栈的操作的时候,一定要保证在RET这条指令之前,ESP指向的是我们压入栈中的地址。这也就是著名的“堆栈平衡”原理! 3.狭义ESP定律 ESP定律的原理就是“堆栈平衡”原理。 让我们来到程序的入口处看看吧! 1.这个是加了UPX壳的入口时各个寄存器的值! EAX 00000000 ECX 0012FFB0 EDX 7FFE0304 EBX 7FFDF000 ESP 0012FFC4 EBP 0012FFF0 ESI 77F51778 ntdll.77F51778 EDI 77F517E6 ntdll.77F517E6 EIP 0040EC90 note-upx.<ModuleEntryPoint> C 0 ES 0023 32bit 0(FFFFFFFF) P 1 CS 001B 32bit 0(FFFFFFFF) A 0 SS 0023 32bit 0(FFFFFFFF) Z 0 DS 0023 32bit 0(FFFFFFFF) S 1 FS 0038 32bit 7FFDE000(FFF) T 0 GS 0000 NULL D 0 O 0 LastErr ERROR_MOD_NOT_FOUND (0000007E) 2.这个是UPX壳JMP到OEP后的寄存器的值! EAX 00000000 ECX 0012FFB0 EDX 7FFE0304 EBX 7FFDF000 ESP 0012FFC4 EBP 0012FFF0 ESI 77F51778 ntdll.77F51778 EDI 77F517E6 ntdll.77F517E6 EIP 004010CC note-upx.004010CC C 0 ES 0023 32bit 0(FFFFFFFF) P 1 CS 001B 32bit 0(FFFFFFFF) A 0 SS 0023 32bit 0(FFFFFFFF) Z 1 DS 0023 32bit 0(FFFFFFFF) S 0 FS 0038 32bit 7FFDE000(FFF) T 0 GS 0000 NULL D 0 O 0 LastErr ERROR_MOD_NOT_FOUND (0000007E) 呵呵~是不是除了EIP不同以外,其他都一模一样啊! 为什么会这样呢? 我们来看看UPX的壳的第一行: 0040EC90 n> 60 pushad //****注意这里***** 0040EC91 BE 15B04000 mov esi,note-upx.0040B015 PUSHAD就是把所有寄存器压栈!我们在到壳的最后看看: 0040EE0F 61 popad //****注意这里***** 0040EE10 - E9 B722FFFF jmp note-upx.004010CC //JMP到OEP POP就是将所有寄存器出栈! 而当我们PUSHAD的时候,ESP将寄存器压入了0012FFC0--0012FFA4的堆栈中!如下: 0012FFA4 77F517E6 返回到 ntdll.77F517E6 来自 ntdll.77F78C4E //EDI 0012FFA8 77F51778 返回到 ntdll.77F51778 来自 ntdll.77F517B5 //ESI 0012FFAC 0012FFF0 //EBP 0012FFB0 0012FFC4 //ESP 0012FFB4 7FFDF000 //EBX 0012FFB8 7FFE0304 //EDX 0012FFBC 0012FFB0 //ECX 0012FFC0 00000000 //EAX 所以这个时候,在教程上面就告诉我们对ESP的0012FFA4下硬件访问断点。也就是说当程序要访问这些堆栈,从而恢复原来寄存器的值,准备跳向苦苦寻觅的OEP的时候,OD帮助我们中断下来。 于是我们停在0040EE10这一行! 总结:我们可以把壳假设为一个子程序,当壳把代码解压前和解压后,他必须要做的是遵循堆栈平衡的原理,让ESP执行到OEP的时候,使ESP=0012FFC4。 4.广义ESP定律 很多人看完了教程就会问:ESP定律是不是就是0012FFA4,ESP定律的适用范围是不是只能是压缩壳! 我的回答是:NO! 看完了上面你就知道你如果用0012FFA8也是可以的,ESP定律不仅用于压缩壳他也可以用于加密壳!!! 首先,告诉你一条经验也是事实---当PE文件运行开始的时候,也就是进入壳的第一行代码的时候。寄存器的值总是上面的那些值,不信你自己去试试!而当到达OEP后,绝大多的程序都第一句都是压栈!(除了BC编写的程序,BC一般是在下面几句压栈) 现在,根据上面的ESP原理,我们知道多数壳在运行到OEP的时候ESP=0012FFC4。这就是说程序的第一句是对0012FFC0进行写入操作! 最后我们得到了广义的ESP定律,对只要在0012FFC0下,硬件写入断点,我们就能停在OEP的第二句处!! 下面我们来举个例子,就脱壳进阶第一篇吧! 载入OD后,来到这里: 0040D042 N> B8 00D04000 mov eax,Notepad.0040D000 //停在这里 0040D047 68 4C584000 push Notepad.0040584C 0040D04C 64:FF35 00000000 push dword ptr fs:[0] //第一次硬件中断,F9 0040D053 64:8925 00000000 mov dword ptr fs:[0],esp 0040D05A 66:9C pushfw 0040D05C 60 pushad 0040D05D 50 push eax 直接对0012FFC0下硬件写入断点,F9运行。(注意硬件中断) 在0040D04C第一次硬件中断,F9继续! 0040D135 A4 movs byte ptr es:[edi],byte ptr ds:[esi] //访问异常,不管他 shift+F9继续 0040D136 33C9 xor ecx,ecx 0040D138 83FB 00 cmp ebx,0 0040D13B ^ 7E A4 jle short Notepad.0040D0E1 第二次硬件中断。 004058B5 64 db 64 //断在这里 004058B6 89 db 89 004058B7 1D db 1D 004058B8 00 db 00 004058B9 00 db 00 这里也不是,F9继续! 004010CC /. 55 push ebp 004010CD |. 8BEC mov ebp,esp //断在这里,哈哈,到了!(如果发现有花指令,用ctrl+A分析一下就能显示出来) 004010CF |. 83EC 44 sub esp,44 004010D2 |. 56 push esi 快吧!还不过瘾,在来一个例子。 脱壳进阶第二篇 如果按上面的方法断不下来,程序直接运行了!没什么,我们在用另一种方法! 载入后停在这里,用插件把OD隐藏! 0040DBD6 N>^\E9 25E4FFFF jmp Note_tEl.0040C000 //停在这里 0040DBDB 0000 add byte ptr ds:[eax],al 0040DBDD 0038 add byte ptr ds:[eax],bh 0040DBDF A4 movs byte ptr es:[edi],byte ptr ds:[esi] 0040DBE0 54 push esp F9运行,然后用SHIFT+F9跳过异常来到这里: 0040D817 ^\73 DC jnb short Note_tEl.0040D7F5 //到这里 0040D819 CD20 64678F06 vxdcall 68F6764 0040D81F 0000 add byte ptr ds:[eax],al 0040D821 58 pop eax 在这里对0012FFC0下硬件写入断点!(命令行里键入HW 12FFC0)SHIFT+F9跳过异常,就来到OEP的第二行处:(用CTRL+A分析一下) 004010CC /. 55 push ebp 004010CD |. 8BEC mov ebp,esp //断在这里 004010CF |. 83EC 44 sub esp,44 004010D2 |. 56 push esi 004010D3 |. FF15 E4634000 call dword ptr ds:[4063E4] 004010D9 |. 8BF0 mov esi,eax 004010DB |. 8A00 mov al,byte ptr ds:[eax] 004010DD |. 3C 22 cmp al,22 就这样我们轻松搞定了两个加密壳的找OEP问题! 5.总结 现在我们可以轻松的回答一些问题了。 1.ESP定律的原理是什么? 堆栈平衡原理。 2.ESP定律的适用范围是什么? 几乎全部的压缩壳,部分加密壳。只要是在JMP到OEP后,ESP=0012FFC4的壳,理论上我们都可以使用。但是在何时下断点避开校验,何时下断OD才能断下来,这还需要多多总结和多多积累。欢迎你将你的经验和我们分享。 3.是不是只能下断12FFA4的访问断点? 当然不是,那只是ESP定律的一个体现,我们运用的是ESP定律的原理,而不应该是他的具体数值,不能说12FFA4,或者12FFC0就是ESP定律,他们只是ESP定律的一个应用罢了! 4.对于STOLEN CODE我们怎么办? 哈哈,这正是寻找STOLEN CODE最好的办法!当我们断下时,正好断在了壳处理STOLEN CODE的地方,在F8一会就到OEP了! 6.后话 以上的方法原理都是我自己总结,自己的经验,如果有什么不对的地方,有什么没解释清楚的地方。还请海涵!但是如果觉得我很厉害,那就大可不必,因为ESP定律也是别人教我的,不是我第一个提出来的!我只是个比你们早飞一点的菜鸟罢了^-^ 看了上面的文字希望能对你在寻找OEP的时候有帮助,但是别忘了一句话:菜鸟认为找OEP很难,高手认为修复才是最难! 好了,下一篇应该写IAT的修复原理了!让我们共同努力吧! 最后如果转载注明作者并保持文章的完整, 谢谢你看完 |
|
VC6的错误
经过调试发现,::后面的函数无论是什么VC都会被他忽略,不会编译到程序里去,所以::后的函数无论是什么,len都等于4(int的长度)。不过不明白是为什么会这样,期待下一楼解释。 |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值