|
[求助]病毒经常用到的偏移量,请高人指教!
应该是自己动手少了,多试几次就明白了 |
|
新手学习,诸多问题待高手解答.
难道...难道... |
|
新手学习,诸多问题待高手解答.
↓^是地址^↓^^^^是机器码^^^^↓^^^^^^^^^^^^^^^是汇编指令 ^^^^^^^^^^^^^^^^^^↓^^^^^^^是注释^^^^↓ 00403D8D FF15 A0D04000 CALL DWORD PTR DS:[<&kernel32.CreateFile>; kernel32.CreateFileA |
|
[求助]请教一个PE格式的问题.
据说是从 1970.01.01 0时到这个时间的秒数 |
|
[求助]病毒经常用到的偏移量,请高人指教!
自定位代码的最终目的是为了我们的代码在任何地方执行的时候都能够访问到我们自定义的变量。为了便于理解,我们 先看下面的例子: .386 .model flat, stdcall option casemap :none .code start: call nStart nStart: pop ebp sub ebp,offset nStart ret end start 编译成可执行代码的样子: 00401000 >/$ E8 00000000 call 00401005 00401005 |$ 5D pop ebp <- 执行到这时的 esp=00401005 00401006 |. 81ED 05104000 sub ebp, 00401005 <- 执行完这句时 ebp=0 0040100C \. C3 retn 根据机器码可见,call nStart在编译后,nStart被替换成了偏移,而sub ebp,offset nStart中的offset start 被换成 了固定地址00401005。 我们把产生的机器码再放到其他位置上看看: 00402000 >/$ E8 00000000 call 00402005 00402005 |$ 5D pop ebp <- 执行到这时的 esp=00402005 00402006 |. 81ED 05104000 sub ebp, 00401005 <- 执行完这句时 ebp=1000 0040200C \. C3 retn 这时得出的ebp有什么意义呢?很容易看出ebp其实就是这段代码目前所在位置和预先编译时所在位置的偏移。这个偏移 有什么用呢?再看下面的例子: .386 .model flat, stdcall option casemap :none .code start: jmp @F Var db "user32.dll",0 @@: lea edx,Var ret end start 编译成可执行代码的样子: 00401000 >/$ /EB 0B jmp short 0040100D 00401002 |. |75 73 65 72 33> ascii "user32.dll",0 0040100D |> \8D15 02104000 lea edx, dword ptr [401002] <- 执行完这句 edx = 00401002 00401013 \. C3 retn 执行完之后,edx为我们预先定义的字符串的地址,可是,如果我们把这段机器码放到其他位置上,如: 00402000 >/$ /EB 0B jmp short 0040200D 00402002 |. |75 73 65 72 33> ascii "user32.dll",0 0040200D |> \8D15 02104000 lea edx, dword ptr [401002] <- 执行完这句 edx = 00401002 00402013 \. C3 retn 执行完之后,edx依然是00401002,而我们自定义的字符串现在却在00402002的位置上,显然这段代码不能在其他位置上 正确执行。好了,如果我们利用上面提到的技术,把代码写成这个样子: .386 .model flat, stdcall option casemap :none .code start: jmp @F Var db "user32.dll",0 @@: call nStart nStart: pop ebp sub ebp,offset nStart lea edx,[ebp+offset Var] ret end start 编译之后的样子: 00401000 >/$ /EB 0B jmp short 0040100D 00401002 |. |75 73 65 72 3> ascii "user32.dll",0 0040100D |> \E8 00000000 call 00401012 00401012 |$ 5D pop ebp 00401013 |. 81ED 12104000 sub ebp, 00401012 <- 执行完这句 ebp = 0 00401019 |. 8D95 02104000 lea edx, dword ptr [ebp+401002] <- 执行完这句 edx = 00401002 0040101F \. C3 retn 执行完之后,edx为我们预先定义的字符串的地址,如果我们也把这段机器码放到其他位置上呢?如: 00402000 >/$ /EB 0B jmp short 0040200D 00402002 |. |75 73 65 72 3> ascii "user32.dll",0 0040200D |> \E8 00000000 call 00402012 00402012 |$ 5D pop ebp 00402013 |. 81ED 12104000 sub ebp, 00401012 <- 执行完这句 ebp = 1000 00402019 |. 8D95 02104000 lea edx, dword ptr [ebp+401002] <- 执行完这句 edx = 00402002 0040201F \. C3 retn 虽然改变了位置,执行完之后,edx依然是我们预先定义的字符串的地址。 所以无论你把这段机器码写到随机的申请申请的内存空间,还是写到其他进程空间,这段代码都能按我们思路正确执行 。这就是call/pop/sub这种自定位技术的魅力。 |
|
[求助]学习API HOOK 的问题
异常处理完毕后程序又从异常发生处恢复执行了,即继续invoke DialogBoxParam, hInstance, offset szDlgName, 0, WndProc, 0去了,第二个对话框是他. SetHook不是在异常处理中执行的 |
|
[求助]学习API HOOK 的问题
(1) ; 把内存保护设置成 可读/可写/可执行: invoke VirtualProtect, [dwAddress], 1, PAGE_EXECUTE_READWRITE, addr dwOldProtect invoke IsDlgButtonChecked, hWnd, IDC_CHECKBUTTON_HOOK mov edx, [dwAddress] test eax, eax .if zero? ; uninstall hook mov cl, [bOldByte] ; bOldByte = API 原入口地址 mov byte ptr [edx], cl ; 恢复 API 的原入口地址 invoke lstrcpy, addr szMsgAbout, addr szText ; 恢复原对话框的输出文字: .else ; re-install hook mov cl, byte ptr [edx] ; byte ptr [edx] = API 原入口地址 mov byte ptr [edx], 0CCh ; 断点异常(INT 3 指令) mov [bOldByte], cl ; 储存 API 的原入口地址 invoke lstrcat, addr szMsgAbout, addr szMyText ; 改变原对话框的输出文字: .endif 上面就是程序的流程 改变API入口地址处的保护属性 IDC_CHECKBUTTON_HOOK Checked? if not Checked 恢复API入口地址并将显示字符串恢复为存原始字符串 if Checked 将入口首字节改为 CC 并显示字符串改为加入szMyText后的字符串。 (2)&&(3) 这两个问题要放在一起理解: mov eax, [lpContext] mov eax, [eax][CONTEXT.regEsp] mov ecx, [eax] mov [eax], offset SetHook mov [dwRetAddr], ecx 上面这段代码在做什么呢?我想你能理解,只是你没有放在汇编码的状态下去理解。这段代码其实是在改变异常发生时ESP的值,这个ESP里放的是什么呢?你已经知道了,就是CALL API时push进的返回地址,上面这段代码把这个地址改写成了 SetHook函数的地址,并对原返回地址进行了保存。这样做起到什么作用呢? 我们此时看下程序流程,假设程序代码如下: AAA CALL API BBB 我们在Call入API时第一条指令发生了异常(此时堆栈顶为BBB处地址),程序进入异常处理程序。异常处理程序中改变了异常发生时的栈顶内容,即把栈顶的BBB处地址改写成了SetHook的地址,然后把CC改写成了原代码。异常处理完毕后,程序继续到异常发生处执行。当API调用完毕准备返回的时候,因为我们改写了返回地址,所以程序将进入SetHook中执行,我们看SetHook的代码: mov eax, [dwAddress] mov cl, [eax] mov byte ptr [eax], 0CCh ; 断点异常(INT 3 指令) mov [bOldByte], cl jmp [dwRetAddr] ; 跳回经过 Hook 之后的 API 的返回地址(很重要!) 上面很好理解,程序将API入口第一字节再次改为CC,并将程序引导到BBB处。至此,程序在被我们改变了流程之后又进入了原来的轨道。 好了,现在我们可以站在全局的高度理解下程序流程(我只列出关键部分): 1 初始化时,获取API的地址和第一字节代码进行保存。 2 运行后通过判断CheckButton是还先中来设定CC或清除CC 3 如果已设定CC,点OK CALL API时则进入SEH Handler 3.1 改变返回地址,恢复原代码 3.2 API 执行完后,进入SetHook再次恢复CC,并将程序引入原轨道。 。。。。。。。 为什么要改变返回地址,最后还又引回原地址,当然是为了设置CC,为了程序完美,你可以试想一下不这样做的结果。 (4) 调试ASM程序用OD,我感觉还是不错的 不知道我说明白了没有,仅供参考吧 |
|
[原创]解决OD载入DLL后无法停在入口处的问题
学习了。。。谢谢 |
|
[求助]学习API HOOK 的问题
invoke GetProcAddress, eax, addr szProcMsgBoxInddwAddress 存放的就是 MessageBoxIndirect 的地址 |
|
|
|
[求助]学习API HOOK 的问题
并不是在那里出现了异常。 此程序是在 API(MessageBoxIndirectA)的入口放入int3(CC)使程序在调用MessageBoxIndirectA时产生单步异常,从而使程序进入我们设计的SEH里来达到HOOK的目的 个人意见,仅供参考。 |
|
|
|
[求助]这种是什么编码方式
看着有点眼熟,有点像uedit的注册文件 |
|
[求助]JE前面是一个CALL,怎么判断跳转条件?
F7进去我想是对的,但不一定是最后一条语句 |
|
[求助]在OLLYDBG中看到这是注册码吗?它和注册码有什么关系?
确定是不是注册码是需要跟踪的,不过你到是可以去试一试 |
|
[原创]干掉KV 2008, Rising等大部分杀软
收藏学习,再次佩服一个大米同学。。。 |
|
[Windows源码分析](一)初始化内核与执行体子系统
趴在地上也要学习。。 |
|
[原创]爆Logicon Trial 破文
支持一下。。 |
操作理由
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 }}
勋章
兑换勋章
证书
证书查询 >
能力值