利用 Debug API 编写一个简单的脱壳机

逆向工程实战:VMP 3.x x64壳导入表修复与VMPDump工具应用 在软件安全与逆向工程领域,导入表是Windows PE文件的核心数据结构,它记录了程序运行时需要调用的外部函数地址,是程序与操作系统交互的桥梁。其工作原理是通过导入地址表在加载时由系统加载器动态填充,确保代码能正确链接到系统API。理解并修复导入表对于软件分析、漏洞挖掘和兼容性研究具有重要技术价值,尤其在处理加壳保护的恶意软件或进行软件兼容性调试时。当程序被VMProtect等强壳保护后,其导入表常被加密或劫持,导致脱壳后程序无法运行或分析。本文聚焦于使用VMPDump工具链,针对VMP 3.x x64壳的 阅读详情
 者: 一块三毛钱
邮件: zhongts@163.com
日期: 2005.2.22


脱壳的一般步骤是:查找入口点,中断在入口点,dump 进程,修复输入表。大家一般借助调试器来完成这几步。下面我就来介绍如何通过编程实现一个简单的脱壳机,自动完成上面的

几个步骤。

1. 查找入口点

查找入口点可以利用现有的工具来完成,如 PEiD、PE-Scan 等。通过对 PEiD 中的 GenOEP 插件的逆向工程我们可以找到如下方法来查找入口点。这种方法的根据就是每个编译器编译

出来的程序在入口点处的代码通常是一样的。比如说 VC6 编译的程序,入口点处的部分代码一般都是下面这个样子:

:00434E55 55 push ebp
:00434E56 8BEC mov ebp, esp
:00434E58 6AFF push FFFFFFFF
:00434E5A 68302E4500 push 00452E30
:00434E5F 68A83F4300 push 00433FA8
:00434E64 64A100000000 mov eax, dword ptr fs:[00000000]
:00434E6A 50 push eax
:00434E6B 64892500000000 mov dword ptr fs:[00000000], esp

其中几个被 push 的具体的值可能不同。根据这一点我们就可以在进程中查找上面这部分代码,找到的地方就是入口点。下面来看看具体的代码实现:

.data
g_Delphi_Signs db 55h, 8Bh, 0ECh, 83h, 0C4h, 0, 53h, 0B8h, 0, 0, 0, 0, 0E8h, 0, 0,
0, 0, 8Bh, 1Dh, 0, 0, 0, 0, 8Bh, 3h, 0E8h, 0, 0, 0, 0, 8Bh, 3h
g_VC6_Signs db 55h, 8Bh, 0ECh, 6Ah, 0FFh, 68h, 0, 0, 0, 0, 68h, 0, 0, 0, 0, 64h,
0A1h, 0, 0, 0, 0, 50h, 64h, 89h, 25h, 0, 0, 0, 0

.code
_GetOEP proc lpMem:DWORD, dwLen:DWORD
LOCAL dwOEP

pushad
invoke _InString, lpMem, dwLen, addr g_Delphi_Signs, 32
.if eax
jmp exit_1
.endif

invoke _InString, lpMem, dwLen, addr g_VC6_Signs, 29
.if eax
jmp exit_1
.endif

jmp exit_0

exit_1:
mov dwOEP, eax
popad
mov eax, dwOEP
ret
exit_0:
popad
xor eax, eax
ret
_GetOEP endp

_InString proc lpszStr:DWORD, dwStrLen:DWORD, lpszSubStr:DWORD, dwSubStrLen:DWORD
LOCAL dwPos

pushad
mov eax, dwStrLen
.if eax < dwSubStrLen
jmp exit_0
.endif
sub eax, dwSubStrLen
mov dwStrLen, eax

mov esi, lpszStr
mov edi, lpszSubStr
xor edx, edx

Loop1:
cmp edx, dwStrLen
jz exit_0
xor ecx, ecx
mov al, byte ptr [edi+ecx]
mov bl, byte ptr [esi+edx]
cmp al, bl
jz Loop2
inc edx
jmp Loop1

Loop2:
inc ecx
inc edx
cmp ecx, dwSubStrLen
jz exit_1
mov al, byte ptr [edi+ecx]
mov bl, byte ptr [esi+edx]
cmp al, bl
jz Loop2
test al, al
jz Loop2
sub edx, ecx
inc edx
jmp Loop1

exit_1:
sub edx, ecx
mov dwPos, edx
popad
mov eax, dwPos
ret

exit_0:
popad
xor eax, eax
ret
_InString endp

g_Delphi_Signs 和 g_VC6_Signs 分别对应 Delphi 和 VC6 编译的程序,其中的 0 代表可能不确定的字节。_GetOEP 函数就是具体获得入口点的函数,分别在进程空间中查找每一个特定的

入口点特征代码,如果能找到就说明找到了入口点。查找特征代码又是由函数 _InString 来完成的,具体实现看看代码就清楚了。

2. 中断在入口点

找到了入口点后,需要中断在入口点处准备 dump 进程,通过 Windows 本身提供的 Debug API 可以实现这一点。

invoke CreateProcess, 0, addr szFile, 0, 0, 0, DEBUG_PROCESS + DEBUG_ONLY_THIS_PROCESS,
0, 0, addr StartupInfo, addr ProcInfo2
.if !eax
invoke _OutputInfo, g_hOutputCtl, CTXT("不能创建进程!!!")
jmp l_exit
.endif
.while TRUE
invoke WaitForDebugEvent, addr DbgEvent, INFINITE
.if DbgEvent.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT
;下面这一行代码很重要,否则被调试进程不会完全退出
invoke ContinueDebugEvent, DbgEvent.dwProcessId, DbgEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED
.break
.elseif DbgEvent.dwDebugEventCode==EXCEPTION_DEBUG_EVENT
.if DbgEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT
inc dwCountBP
.if dwCountBP==1 ;第一次中断时在原始入口点处设置断点
invoke _OutputInfo, g_hOutputCtl, CTXT("在原始入口点设置断点...")
mov int3, 0CCh
invoke ReadProcessMemory, ProcInfo2.hProcess, dwOrgOEP, addr org_code, 1, 0
invoke WriteProcessMemory, ProcInfo2.hProcess, dwOrgOEP, addr int3, 1, 0

.elseif dwCountBP==2 ;第二次中断,这次是中断在原始入口点,在 OEP 处设置硬件断点
invoke _OutputInfo, g_hOutputCtl, CTXT("到达原始入口点")

mov g_context.ContextFlags, CONTEXT_CONTROL
invoke GetThreadContext, ProcInfo2.hThread, addr g_context
dec g_context.regEip
invoke WriteProcessMemory, ProcInfo2.hProcess, dwOrgOEP, addr org_code, 1, 0
invoke SetThreadContext, ProcInfo2.hThread, addr g_context

mov g_context.ContextFlags, CONTEXT_DEBUG_REGISTERS
invoke GetThreadContext, ProcInfo2.hThread, addr g_context
m2m g_context.iDr0, dwOEP
mov g_context.iDr7, 1
invoke SetThreadContext, ProcInfo2.hThread, addr g_context

invoke wsprintf, addr buf, CTXT("在 OEP: %08lXh 处设置硬件断点..."), dwOEP
invoke _OutputInfo, g_hOutputCtl, addr buf
.endif
invoke ContinueDebugEvent, DbgEvent.dwProcessId, DbgEvent.dwThreadId, DBG_CONTINUE
.continue
.elseif DbgEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP
;第三次中断,来到真正的入口点,抓取进程,然后终止进程
invoke wsprintf, addr buf, CTXT("中断在 OEP: %08lXh 处"), dwOEP
invoke _OutputInfo, g_hOutputCtl, addr buf
invoke _OutputInfo, g_hOutputCtl, CTXT("清除硬件断点...")

mov g_context.ContextFlags, CONTEXT_FULL
invoke GetThreadContext, ProcInfo2.hThread, addr g_context
mov g_context.iDr0, 0
mov g_context.iDr7, 0
invoke SetThreadContext, ProcInfo2.hThread, addr g_context

invoke _OutputInfo, g_hOutputCtl, CTXT("抓取进程...")
invoke _Dump, ProcInfo2.hProcess, dwImageBase, dwSizeOfImage, lpMem
invoke TerminateProcess, ProcInfo2.hProcess, 0
invoke ContinueDebugEvent, DbgEvent.dwProcessId, DbgEvent.dwThreadId, DBG_CONTINUE
.continue
.endif
.endif
invoke ContinueDebugEvent, DbgEvent.dwProcessId, DbgEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED
.endw
invoke CloseHandle, ProcInfo2.hThread
invoke CloseHandle, ProcInfo2.hProcess
mov ProcInfo2.hProcess, 0

关键技术就是要在入口点处设置一个硬件断点,从而中断在入口点处准备 dump 进程。这里要设置硬件断点而不能设置一个 int3 断点的原因是我们设置断点的时候外壳还没有解密程序代码

。如果我们在入口点处写入一个 0CCh 字节来设置一个 int3 断点,当外壳把程序代码解密后,入口点处的 0CCh 字节又会被解密后的代码覆盖,所以 int3 断点不起作用。

3. dump 进程

中断在入口点处了就可以 dump 进程,这个代码很简单

_Dump proc hProcess:DWORD, lpBaseAddress:DWORD, dwSize:DWORD, lpBuffer:DWORD
pushad
invoke ReadProcessMemory, hProcess, lpBaseAddress, lpBuffer, dwSize, 0
popad
ret
_Dump endp

4. 修复输入表

修复输入表可以利用 ImpREC.dll 来完成,这个也很简单,只需调用一个 RebuildImport 函数就可以搞定。

mov g_lpRebuildImport, 0
invoke LoadLibrary, CTXT("ImpREC.dll")
.if eax
mov ebx, eax
invoke GetProcAddress, ebx, CTXT("RebuildImport")
.if eax
mov g_lpRebuildImport, eax
.else
invoke _OutputInfo, g_hOutputCtl, CTXT("不能从 ImpREC.dll 中引入 RebuildImport 函数")
invoke _OutputInfo, g_hOutputCtl, CTXT("脱壳后的文件不能重建输入表!!!")
.endif
.else
invoke _OutputInfo, g_hOutputCtl, CTXT("找不到 ImpREC.dll 文件")
invoke _OutputInfo, g_hOutputCtl, CTXT("脱壳后的文件不能重建输入表!!!")
.endif

invoke CreateProcess, NULL, addr szFile, NULL, NULL, NULL, NORMAL_PRIORITY_CLASS, /
NULL, NULL, addr StartupInfo, addr ProcInfo3
invoke WaitForInputIdle, ProcInfo3.hProcess, -1
invoke _OutputInfo, g_hOutputCtl, CTXT("重建输入表...")
mov ecx, dwOEP
sub ecx, dwImageBase
lea eax, g_buffer

push eax
push 5
push 0
push ecx
push ProcInfo3.dwProcessId
call g_lpRebuildImport ;调用 ImpREC.dll 中的 RebuildImport 函数重建输入表

.if eax==0
invoke _OutputInfo, g_hOutputCtl, CTXT("重建输入表失败!!!")
.else
invoke DeleteFile, addr g_buffer
lea esi, g_buffer
invoke lstrlen, esi
add esi, eax
sub esi, 4
invoke lstrcpy, esi, CTXT("_.exe")
.endif
invoke TerminateProcess, ProcInfo3.hProcess, 0

后记
Unity Mono安卓游戏逆向实战:Frida Hook绕过碰撞死亡判定 在移动应用安全与游戏逆向工程领域,运行时Hook技术是分析、修改程序逻辑的核心手段之一。其原理是通过注入代码,在目标函数执行前后插入自定义逻辑,从而实现对程序行为的监控或篡改。这项技术的价值在于,它允许研究者在无需源码的情况下,深入理解应用内部机制、进行安全评估或实现特定功能。在Unity引擎开发的安卓游戏中,尤其是采用Mono后端的项目,游戏逻辑通常由C#编写并编译为托管DLL。通过结合静态分析工具(如dnSpy)与动态Hook框架(如Frida),可以精准定位并拦截关键的游戏函数,例如处理伤害计算或状态 阅读详情

相关推荐

易语言EXE反编译原理与工具解析:从伪编译机制到安全分析实践

在软件逆向工程领域,反编译技术是将已编译的二进制程序转换回高级语言伪代码的关键过程,其核心原理在于解析程序的指令集、数据结构与控制流。这项技术的价值不仅体现在代码恢复与软件维护上,更是安全研究、漏洞挖掘和恶意代码分析的基础工具。通过理解编译器优化、运行时库绑定和资源存储机制,分析人员能够穿透代码混淆与加密保护,还原程序的真实逻辑。在应用场景上,反编译技术广泛应用于软件安全审计、遗留系统重构以及知识产权保护。本文聚焦于易语言这一独特的中文编程生态,深入剖析其伪编译与支持库机制如何导致通用反编译工具失效,并详解

weixin_33728708的博客 495

逆向基础-脱壳

逆向基础-脱壳

AppWhite_Star的博客 2450

Android应用脱壳实战:反射大师工具原理与dnguard hvm强壳对抗

在移动应用安全领域,加壳技术通过加密、混淆和虚拟机保护等手段保护应用代码,防止逆向分析和篡改。其核心原理是在原始应用文件外包裹保护层,运行时动态解密执行。脱壳作为逆向工程的基础环节,旨在从内存中提取解密后的原始代码,对安全研究、漏洞挖掘至关重要。面对dnguard hvm等采用深度虚拟化技术的高强度商业壳,传统静态分析失效,需依赖动态脱壳工具。反射大师作为Android平台动态脱壳工具,通过注入目标进程、利用反射机制提取内存中的DEX文件,结合Frida动态插桩技术,实现对强壳的有效对抗。本文聚焦于脱壳环境

weixin_29322855的博客 306

aspack的简单脱壳,望大牛勿喷。

压缩壳下面是我的脱壳,win7x64下测试。1.单步跟踪2.ESP定律3.一步到达oep4.内存镜像法5.脱壳软件6.脚本脱壳7.模拟跟踪法,查看内存。SFX,imports,relocationstceip<地址,另外说下,这个跟踪好慢。。8.Sfx法以上方法第一种脱壳后还是来个脱壳机试试吧。话说区段一点也不一样。名字都乱了啊,文件也打不开。怀疑脱壳机有问题。AsP...

weixin_33762130的博客 798

APKiD与Yara规则在Android应用安全分析中的原理与实践

在移动安全领域,静态分析是识别应用潜在风险的基础技术。其核心原理是通过对应用二进制文件进行模式匹配,快速识别其编译器、加壳工具、混淆方案等关键指纹信息。这项技术的价值在于,它能帮助安全研究人员和逆向工程师在深入分析前,快速了解目标的防御工事,从而制定高效的分析策略。Yara规则作为一种强大的模式匹配语言,因其语法简洁、性能优异且社区活跃,成为实现这一目标的理想工具。通过编写特定的Yara规则,可以精准匹配文件魔数、特定字符串或字节序列等特征。在Android应用安全分析场景中,APKiD工具正是基于Yara

338

软件安全与逆向分析入门:从二进制基础到实战CrackMe

二进制是计算机执行的核心机器语言,理解其原理是深入软件内部逻辑的基础。通过分析二进制代码,可以洞悉程序运行机制,这一过程构成了软件逆向工程与安全分析的技术核心。掌握这项技能对于漏洞挖掘、恶意软件分析和软件兼容性开发具有重要价值。在实际应用中,工程师常借助反汇编器、调试器等工具链,结合静态分析与动态调试的方法,对软件进行剖析。例如,在分析一个序列号验证程序(CrackMe)时,通过查壳、字符串分析定位关键函数,并利用调试器验证算法逻辑,最终理解其验证机制。这个过程自然地融入了对软件保护机制(如加壳、混淆)的初

culi3118的博客 345

APK加固之静态脱壳机编写入门

1. 加固的作用加固保护做用 :加密、防逆向、防篡改、反调试、反窃取 破解的目的 : 原始的dex数据,解密算法,解密密钥; 困难 : 获取这些信息必要通过到内存中过去修改反调试,动态分析破解流程,获取密钥,获取原来的dex数据存放位置 2. 加固前后区别 readelf -a **.so 文件名 可以查看so库各种信息 so库加壳特征之一(可能是因为so库加壳的方式不同吧) 可以发现

Change the World by Program 1012

zprotect 1.6 脱壳工具(附源码)

zprotect 1.6 脱壳工具 本次直接把 源代码 一并发布!

移动端API签名逆向实战:从抓包到算法复现的完整方法论

在移动应用安全与通信协议分析领域,API签名是保障数据传输安全与身份验证的核心机制。其基本原理是通过特定算法,将请求参数与密钥结合生成唯一标识,防止请求被篡改或伪造。从技术价值看,理解签名机制不仅是安全测试的基石,也是进行协议分析、数据合规审查及兼容性开发的关键。常见的应用场景包括安全评估、逆向工程学习及自动化测试工具开发。本文以某移动应用的_sig参数为例,详细拆解了从网络抓包、静态反编译到动态Hook的完整分析流程,并最终通过Python实现了算法复现。整个过程深入运用了Frida动态调试与HMAC-S

weixin_33924770的博客 542

红黑全能自动脱壳机——非常强大的脱壳工具

红黑全能自动脱壳机 非常强大的脱壳工具 下面是它能脱的壳: upx 0.5x-3.00 aspack 1.x--2.x PEcompact 0.90--1.76 PEcompact 2.06--2.79 NsPack nPack FSG 1.0--1.3 v1.31 v1.33 v2.0 VGCrypt0.75 expressor 1.0--1.5 dxpack v0.86 v1.0 !Epack v1.0 v1.4 mew1.1 packMan 1.0 PEDiminisher 0.1 pex 0.99 petite v1.2 - v1.4 petite v2.2 petite v2.3 winkript 1.0 pklite32 1.1 pepack 0.99 - 1.0 pcshrinker 0.71 wwpack32 1.0 - 1.2 upack v0.10 - v0.32 upack v0.33 - v0.399 RLPack Basic Edition 1.11--1.18 exe32pack v1.42 kbys 0.22 0.28 morphine v1.3 morphine v1.6 morphine v2.7 yoda's protector v1.02 yoda's protector v1.03.2 yoda's crypt v1.2 yoda's crypt v1.3 EXE Stealth v2.72--v2.76 bjfnt v1.2 - v1.3 HidePE 1.0--1.1 jdpack v1.01 jdpack v2.0 jdpack v2.13 PEncrypt v3.1 PEncrypt v4.0 Stone's PE Crypt v1.13 telock v0.42 telock v0.51 telock v0.60 telock v0.70 telock v0.71 telock v0.80 telock v0.90 telock v0.92 telock v0.95 v0.96 v0.98 v0.99 ezip v1.0 hmimys-packer v1.0 jdprotect v0.9b lamecrypt UPolyX v0.51 StealthPE 1.01 StealthPE 2.2 depack 涛涛压缩器 polyene 0.01 DragonArmour EP Protector v0.3 闪电壳(expressor) BeRoEXEPacker PackItBitch 木马彩衣 mkfpack anti007 v2.5 v2.6 yzpack v1.1 v1.2 v2.0 spack_method1 v1.0 v1.1 v1.2 v1.21 spack_method2 v1.1 v1.2 v1.21 xj1001 xj1000 xj看雪测试版 xj1003 xpal4 仙剑-凄凉雪 仙剑-望海潮 mslrh0.31 v0.32 [G!X]'s Protect

RL!dePacker1.4汉化版(一款自动脱壳工具).

RL!dePacker1.4汉化版(一款自动脱壳工具).zxwmol

关于EXECryptor参数设置的问题

关于EXECryptor参数设置的问题 最近加壳一个字符处理的软件。发觉EXECryptor使用中存在的一些问题。 在某些xp sp3的机器上,anti-debug如果勾选就无法运行,而我笔记本上可以运行。 在我笔记本的xp sp3能运行,而在win7里又无法运行。 经过多个选项组合的加壳后分别测试。发觉: 在我xp sp3: virtualization-level: 20-...

csstome 205

实现通用脱壳机

本教程介绍了各种常见的加壳/脱壳的原理和技术,并给出了实现通用脱壳机的方法

ASPROTECT 2.x 脱壳系列(一)

ASPROTECT 2.x 脱壳系列(一)【目    标】:DVD Fab Gold 2.9.4.2【工    具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F【任    务】:简单的脱壳【操作平台】:Windows XP sp2【作    者】: LOVEBOOM[DFCG][FCG][US]【相关链接】: 自己搜索下【简要说明】: 时间在不断的减少,人越靠近死亡的

loveboom's Reverse Enginering 1万+

VMProtect 1.xx - 2.xx自动脱壳机(脚本)+教程

LCF-AT 是个传奇,脱壳牛人。他跟 Raham 都是研究脱壳,不研究破解的。两个都是脱壳牛人。VMProtect 1.xx - 2.xx自动脱壳机(脚本)+教程(密码tuts4you)

四百八十多个脱壳脚本汇总,包含国内主流加壳软件各种版本的脱壳脚本,很全面

四百八十多个脱壳脚本汇总,包含国内主流加壳软件各种版本的脱壳脚本,很全面

2021-11-20~21 Re 逆向工程略览 四 动态调试与分析【T.O.CTF】

作为一个成熟 (笑) 的Rer,应该都已经在C程序的学习中使用过编译器的Debug功能,这些让程序实际运行起来,观察程序运行时的各种变化与行为,从而对程序进行分析。今天,我们来聊聊动态调试。

Menou16的博客 1737

phaser3适配微信小游戏

phaser3适配微信小游戏

SilenzioX的博客 1806

逆向工程检测后门:从二进制解剖到攻击链还原实战指南

在网络安全领域,逆向工程是一项通过分析软件二进制代码来理解其内部逻辑与工作机制的核心技术。其原理在于将编译后的程序进行反汇编与反编译,从机器指令层面还原出可读的控制流与数据流,从而透视软件的真正意图。这项技术的核心价值在于能够突破黑盒限制,在缺乏源代码的情况下,深度检测隐蔽的后门、漏洞或恶意行为,尤其适用于分析供应链攻击、无源码组件及高级持续性威胁(APT)中的定制化恶意代码。从应用场景看,逆向工程广泛应用于恶意软件分析、漏洞挖掘、软件安全审计及数字取证。本文聚焦于如何系统性地运用逆向工程这一“手术刀”,结

weixin_30530339的博客 384

安防相机宽动态(WDR)技术解析:从原理到实战应用

本文深入解析安防相机宽动态(WDR)技术原理,对比多次曝光与DOL-WDR等实现方式,并区分硬件WDR与数字WDR(DWDR)的本质差异。文章重点阐述了WDR在逆光出入口、夜间道路监控等五大典型场景的实战应用与调参技巧,旨在帮助用户根据实际需求正确选择与配置,确保监控系统在复杂光线下清晰成像。

weixin_29191081的博客 429

Blender.粒子效果

Blender.粒子效果 ✦ shift+A新建一个棱角球,细分(之后要分解成许多小颗粒) ✦ 给球添加粒子系统,这时播放粒子会向下掉,力场权重☛重力☛0后,粒子会在球体周围运动 ✦ shift+A添加一个力场,调整力场强度 ✦如果粒子运动太快,我们可以在输出属性中调整时间重映射的原始值 ✦想让粒子在球周围运动而不是发散出去,在物理属性找到力场设置,调整流的大小 ✦S键将球形缩小到看不见 ✦给粒子变添加立方体的形状,在粒子属性里找到渲染选项,将“光晕”改为“物体”,在实例物体中选择新建的立方

weixin_46385629的博客 6670
上一篇: 一款木马的分析
下一篇: peid逆向记录
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值