破穿山甲(Armadillo 3.XX-4.XX)
上次介绍了Armadillo的四种保护选项,对四种保护选项有了了解之后就可以破解了。破解Armadillo的基本方法分为六步:
1、到达OEP(脚本来完成)
需要记录:入口的头2字节
OEP的头2字节
OEP=
PID=
在找OEP之前我们需要对程序使用了哪几个保护选项有个了解,可以用Armadillo find protected 1.3.exe来查它使用了哪几个保护选项,
下面公布一个很好用的Armadillo的脱壳脚本,这个脚本还是很强大的可以很方便的到达OEP,可以为我们省去很多事,将以下代码保存为txt格式就可以在OD中采用脚本方式脱了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | //////////////////////////
// To declare vars
/////////////////////////
var WaitForDebugEvent
var WriteProcessMemory
var pDebugEvent
var pBuffer
var child_ProcID
var oep_offset1
var oep_offset2
var oep_offset3
var crypto_proc
var child_OEP
var patched_line1
var imgbase
var rdata_begin
var text_begin
var text_patch
var tb_report1
var tb_report2
var tb_report3
var tb_report4
var tb_report5
var tb_report6
var addr_1000
var buffer_1000
var temp
var temp1
//////////////////////////////////////
// Find rdata_begin or (data_begin)
/////////////////////////////////////
gmi eip,MODULEBASE
mov imgbase, $RESULT
mov rdata_begin, imgbase
find rdata_begin, #4441544100# //find "DATA" string
cmp $RESULT,0
jne lbcontinue
find rdata_begin, #2E726461746100# //find ".rdata" string
cmp $RESULT,0
jne lbcontinue
find rdata_begin, #2E6461746100# //find ".data" string
cmp $RESULT,0
jne lbcontinue
jmp no_run_script
lbcontinue:
mov rdata_begin, $RESULT
add rdata_begin, 0c
mov rdata_begin, [rdata_begin]
add rdata_begin, imgbase
log rdata_begin
/////////////////////////////////
// Find text_begin
////////////////////////////////
gmi eip,MODULEBASE
mov imgbase, $RESULT
mov text_begin, imgbase
find text_begin, #434F444500# //find "CODE" string
cmp $RESULT,0
jne lbcontinue2
find text_begin, #2E7465787400# //find ".text" string
cmp $RESULT,0
jne lbcontinue2
jmp no_run_script
lbcontinue2:
mov text_begin, $RESULT
add text_begin, 0c
mov text_begin, [text_begin]
add text_begin, imgbase
log text_begin
/////////////////////////////////////////////////////
//eob found_WaitForDebugEvent WriteProcessMemory
////////////////////////////////////////////////////
gpa "WaitForDebugEvent", "kernel32.dll"
mov WaitForDebugEvent, $RESULT
gpa "WriteProcessMemory", "kernel32.dll"
mov WriteProcessMemory, $RESULT
///////////////////////////////////////
//Armadillo check bp first 5 bytes so:
///////////////////////////////////////
add WriteProcessMemory,5
bp WriteProcessMemory
run
bc WriteProcessMemory
sub WriteProcessMemory,5
//////////////////////////////////////////////
//Get infomation at bp Call WaitForDebugEvent
/////////////////////////////////////////////
bp WaitForDebugEvent
run
bc WaitForDebugEvent
mov pDebugEvent, esp
add pDebugEvent, 04
mov pDebugEvent, [pDebugEvent]
log pDebugEvent
mov oep_offset1, pDebugEvent
add oep_offset1, 18
mov oep_offset2, pDebugEvent
add oep_offset2, 24
mov oep_offset3, pDebugEvent
add oep_offset3, 28
////////////////////////////////////////
// Find Child_ProcID and child_OEP
///////////////////////////////////////
bp WriteProcessMemory
run
bc WriteProcessMemory
mov child_ProcID, pDebugEvent
add child_ProcID, 4
mov child_ProcID, [child_ProcID]
mov child_OEP, [oep_offset1]
///////////////////////////////////
//Save info Table report
///////////////////////////////////
mov tb_report1,[pDebugEvent]
mov tb_report2,pDebugEvent
add tb_report2,4
mov tb_report2,[tb_report2]
mov tb_report3,pDebugEvent
add tb_report3,8
mov tb_report3,[tb_report3]
mov tb_report4,pDebugEvent
add tb_report4,C
mov tb_report4,[tb_report4]
mov tb_report5,pDebugEvent
add tb_report5,10
mov tb_report5,[tb_report5]
mov tb_report6,pDebugEvent
add tb_report6,14
mov tb_report6,[tb_report6]
////////////////////////////////////////////////////
//Get info in stack at bp Call WriteProcessMemory
///////////////////////////////////////////////////
mov addr_1000,esp
add addr_1000,8
mov addr_1000,[addr_1000]
log addr_1000
mov buffer_1000,esp
add buffer_1000,C
mov buffer_1000,[buffer_1000]
log buffer_1000
/////////////////////////////////
//Patch OEP of Son to EBFE
/////////////////////////////////
mov temp,child_OEP
sub temp,addr_1000
add temp,buffer_1000
mov temp1,[temp]
and temp1,FFFF
eval "Bytes patched at OEP of Son (to invert the bytes order) : {temp1}"
msg $RESULT
log $RESULT
fill temp,1,eb
add temp,1
fill temp,1,fe
///////////////////////////
// FIND ENCRYPTOR
///////////////////////////
mov crypto_proc, esp
add crypto_proc, 128
mov crypto_proc, [crypto_proc]
add crypto_proc, 2d0
mov [crypto_proc], #9090909090#
rtr //ctrl-f9
sto //f8
///////////////////////
//Log info to win log
//////////////////////
log "crypto_proc was nopped..."
log "patched OEP of child process to EBFE"
log child_ProcID
log child_OEP
log "press script/resume when ready"
eval "Patched successful OEP={child_OEP} of child process (PID= {child_ProcID}) to EBFE !!!!.More Info in Window Log.Press button OK to continues!"
msg $RESULT
////////////////////////////////////////////////////////////////
//Patch jump to section .text and NOPs call WaitForDebugEvent
///////////////////////////////////////////////////////////////
bp WaitForDebugEvent
run
bc WaitForDebugEvent
mov patched_line1, [esp]
sub patched_line1, 12
fill patched_line1, 12, 90
add patched_line1,14
eval "jmp {text_begin}"
asm patched_line1,$RESULT
add patched_line1,5
eval "NOP"
asm patched_line1,$RESULT
//////////////////////////////////////
//Patch in section .text (or CODE)
//////////////////////////////////////
mov text_patch, text_begin
eval "add dword [{oep_offset1}],1000"
asm text_patch,$RESULT
add text_patch,A
eval "add dword [{oep_offset2}],1000"
asm text_patch,$RESULT
add text_patch,A
eval "add dword [{oep_offset3}],1000"
asm text_patch,$RESULT
add text_patch,A
eval "cmp dword [{oep_offset3}],{rdata_begin}"
asm text_patch,$RESULT
add text_patch,A
eval "jnz {patched_line1}"
asm text_patch,$RESULT
add text_patch,6
eval "push {child_ProcID}"
asm text_patch,$RESULT
add text_patch,5
eval "CALL DebugActiveProcessStop"
asm text_patch,$RESULT
add text_patch,5
eval "NOP"
asm text_patch,$RESULT
//////////////////////////////
//Patch in Table report at :
//////////////////////////////
sub text_begin,1000
mov [oep_offset1], text_begin
mov [oep_offset2], text_begin
mov [oep_offset3], text_begin
//////////////////////////////////
//go [esp](New origin here)
///////////////////////////////////
mov eip, [esp]
//////////////////////////
// Set bp F2 at
/////////////////////////
bp text_patch
run
bc text_patch
msg "Successful!.Close OllyDbg, execute again and attach to your newely created process.More Info in Window Log. Have fun."
jmp theend
//////////////////////////////////
no_run_script:
msg "This srcipt don't run with this file. Plz Close Olly.Sorry!"
///////////////////////////////
theend:
ret |
记录了以上数据之后就可以在OD中附加PID数据了,将新的头字节还原成程序的原OEP的头两个字节,下面就可以进入第三步了。
2、找、处理IAT
在OD中,ctrl+B查找FF 25,就可以找到程序的IAT了,然后就进入到处理IAT了,再打开一个OD
3、Code Splicing处理
4、挪动IAT
5、Nanomites处理
6、可能还有校验需要处理