Intro
_Tui mới viết lại cái tut này, do cái tut cũ bị mất. Trong tut này chúng ta sẽ tìm hiểu về
CopyMem protection. Đây là một dạng rất đỉnh. Nếu bạn làm tốt với dạng này thì bạn đã gần
đạt thượng thừa của Armadillo Unpacking chỉ còn tầng cuối cùng là Nanomites. Bạn đã biết
debug blocker rồi, nhưng CopyMem thì bạn nghe nói đến nhưng không hiểu nó là gì. Và thực tế
là bạn có thể hiểu nhưng chưa từng bắt tay vào unpack nó cả. Thực tế cho thấy không phải bạn
không giỏi mà tại chúng ta mắc một dạng ỳ tâm lý. Nghe nó tới Armadillo là sợ xanh mặt, chẳng
cần biết là nó thuộc dạng nào! Giống như câu đố: “ Một con mèo ăn một con chuột trong 3 giây,
hỏi 30 con mèo ăn 30 con chuột trong bao nhiêu giây?” thì hầu hết mọi người trả lời là 30 giây!
Bạn cũng thấy đó, qua 3 tut vừa rồi Armadillo không khó như ta nghĩ phải không ?
_ Bạn Merc mới share cho các bạn một bản OllyDBG có giao diện cực cool của tSRH mod lại. Tui
cũng có down về. Đây là bản chưa patch nên các bạn không thể dùng để unpack Armadillo. Mà
tác giả can thiệp thô bạo vào Resource, lại dấu diếm bằng cách pack ASPack, không thể unpack.
Tôi đành phải làm một bản có giao diện giống như bản của Merce share. Bản này chạy trơn tru
với Armadillo. Đây là một món quà tôi tặng các bạn cho tut cuối cùng này. Sau tut này tôi offline
có việc, chắc phải 1 tháng nữa mới ngồi lại với PC. Khi đó hy vọng vào gặp lại các bạn thấy tất
cả đã là pro.
30 trang |
Chia sẻ: tlsuongmuoi | Lượt xem: 2374 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Armadillo x.xx - Debug Blocker+ CopyMemII, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Armadillo-Góp nhặt cát đá
Phần 4: Armadillo x.xx- Debug Blocker+CopyMemII
I. Intro
_Tui mới viết lại cái tut này, do cái tut cũ bị mất. Trong tut này chúng ta sẽ tìm hiểu về
CopyMem protection. Đây là một dạng rất đỉnh. Nếu bạn làm tốt với dạng này thì bạn đã gần
đạt thượng thừa của Armadillo Unpacking chỉ còn tầng cuối cùng là Nanomites. Bạn đã biết
debug blocker rồi, nhưng CopyMem thì bạn nghe nói đến nhưng không hiểu nó là gì. Và thực tế
là bạn có thể hiểu nhưng chưa từng bắt tay vào unpack nó cả. Thực tế cho thấy không phải bạn
không giỏi mà tại chúng ta mắc một dạng ỳ tâm lý. Nghe nó tới Armadillo là sợ xanh mặt, chẳng
cần biết là nó thuộc dạng nào! Giống như câu đố: “ Một con mèo ăn một con chuột trong 3 giây,
hỏi 30 con mèo ăn 30 con chuột trong bao nhiêu giây?” thì hầu hết mọi người trả lời là 30 giây!
Bạn cũng thấy đó, qua 3 tut vừa rồi Armadillo không khó như ta nghĩ phải không ?
_ Bạn Merc mới share cho các bạn một bản OllyDBG có giao diện cực cool của tSRH mod lại. Tui
cũng có down về. Đây là bản chưa patch nên các bạn không thể dùng để unpack Armadillo. Mà
tác giả can thiệp thô bạo vào Resource, lại dấu diếm bằng cách pack ASPack, không thể unpack.
Tôi đành phải làm một bản có giao diện giống như bản của Merce share. Bản này chạy trơn tru
với Armadillo. Đây là một món quà tôi tặng các bạn cho tut cuối cùng này. Sau tut này tôi offline
có việc, chắc phải 1 tháng nữa mới ngồi lại với PC. Khi đó hy vọng vào gặp lại các bạn thấy tất
cả đã là pro.
_ What is that so called CopyMEM protection and what does debugger blocking mean?
When an Armadillo protected Application starts executing, it creates also another
process.This process is called child,and the first executed exe is called father.
So,when you will run it under Olly and check in process list,you will find two processes with the
same name,with different ID's.The red one in process list is the current proccess Olly
debugs,and is the father,and the black one is the child.
So,debugger blocking is actually the incapabillity of Olly as a Ring-3 debugger to
debugg the child,which is the "REAL" actuall process that we want to make a Dump,cause the
child is a seperate during runtime created process.
Now,when the father decides to create the child process,will allocate memory dynamically.The
father will create the child with all the sections similar to him (cause is the same program
actually) except two sections (maybe more in other applications):Code section.Of course,IAT
section will also not be similar,cause in father is filled with 00's and in child if filled with
redirected calls.
At start,code section of child is filled with 00's.When the child has to start running from OEP,
this will cause an exception to the father, cause as i said, in memory (code section) are 00's.
The father will realize that and will copy the first 1000h bytes to the child. So, in this starting
point, OEP will be between the memory locations that father is filling with the original decrypted
code.The father will also copy an encryption-decryption routine for this memory space in
child,that will be responsible for encrypting during runtime this part of code,when EIP of child
will not be between the ranges of the just copied bytes.Then,father will copy the next original
1000h bytes to the child, and the next till it fills all the code section of child.Now,the child is
independant to start running alone actually.So,runs the first block of 1000h bytes (which OEP is
inside these memory bounds),and all other blocks of 1000h bytes in child are encrypted.If EIP
passes the limits of that memory space (a call or a jmp or just code execution) the child
encrypts this 1000h bytes blocks and decrypts the requested,that EIP is inside it now.And this
thing continues till the exit of the program.So,cause of those memory copies that happen
continually ,and becuase it is the second version of that techik is called CP2 or Copymem2.
_Nói tóm lại khi Defeat CopyMemII ta cần hiểu rằng father sẽ write 1000 bytes vào đoạn code.
Trong đoạn code này, bắt buột phải chứa OEP. Bằng thuật toán vét cạn, chúng ta sẽ xác định
chính xác OEP. Giải mã đoạn code này. Dump và fix IAT như dạng code splicing.
II. Tools
_Công cụ cần có chỉ là:
1.OllyDBG - The best config debugger for Armadillo unpacking by hacnho.
2.PETools 1.5RC5
3.Import REConstructor 1.6 Final
4.P.U.P.E. 2005 Suite - Universal Process Patcher Pro
5.EditPluss 2.20 Regged (thanx kienmanowar)
6.API Address 1.0
III. Unpacking
_Trước tiên tui sẽ unpack một SnD Unpackme protect kiểu này.
Target#1: SnD Unpackme-Armadillo 4.xx
_Dấu hiệu thứ nhất của CopyMemII là khi ta chạy target mình ên, nó sẽ tồn tại hai process.
Xem:
_Khi load target lên Olly thì chỉ còn 1 process hiện lên:
_Trong OllyDBG, vào Attach menu:
_Khi mới bắt đầu làm quen với Armadillo, đụng ngay một soft là Wealth-Lab Developer 3.0 tui
muốn điên lên, rõ ràng mình thấy nó có hai process mừ, sao attach không được. Vì sao lại thế,
tại sao lại thế :D. Đây là một đặc điểm của CopyMemII.
_Dấu hiệu thứ hai là chúng ta xem coi nó có write 1000 bytes vào đoạn code có chứa OEP trong
child process hay không?
_Load target vào Olly. Alt+F1, bp WaitForDebugEvent. F9 :
_Ta thấy địa chỉ của DebugEvent do process cha tạo ra là 0012CD90. Ghi nhớ lấy nó. Ctrl+F2
restart Olly, Alt+F1, bp WriteProcessMemory, Ctrl+G: 0012CD90. F9 lần thứ nhất:
_F9 lần thứ hai:
_F9 lần thứ ba (để view rõ hơn, chọn Long>Address).
_Nhấn Alt+K để vào stack ta xem:
_Thấy gì qua những thông tin này. OEP chúng ta =4271B0. Process cha sẽ write 1000 bytes vào
process con bắt đầu từ địa chỉ 427000. Lấy 4271B0-427000=1B0<4096 432<1000. Rõ ràng
OEP lọt trong khoảng 1000 bytes.
_Vậy hàm gọi để write 1000 bytes này ở đâu. Cần phải biết nó để nop nó :D.
_Trở lại vấn đề chính! Bạn đang ở đây:
_Xoá Breakpoint WriteProcessMemory đi: bc WriteProcessMemory. Mục đích chúng ta cần tìm
đoạn call, tạm gọi là Magic Call .
_Ctrl+F9 Execute till return. Bạn sẽ ở đây:
_Trong vùng Stack bạn cuộn chuột đến khi gặp đoạn return thứ hai kể từ đoạn return đầu tiên
là:
0012BB58 00482857 RETURN to UnPackMe.00482857 from kernel32 WriteProcessMemory
-Ta thấy được đoạn cần tìm là:
_Ghi nhớ địa chỉ 48180D. Trở lại CPU, Ctrl+G: 48180D.
_Tại sao chúng ta làm điều này. Hiểu rằng trước khi write 1000 bytes để encrypt code có OEP
của ta, hàm WriteProcessMemory cần trỏ đến một hàm Call mà tui gọi là Magic Call. Tại sao tui
Ctrl+F9 vì tui muốn những giá trị trả về của hàm WriteProcess. Ta cần giá trị đầu tiên vì lúc này
tui đã sắp bị write 1000 bytes gòi (tui F9 3 lần, nếu bạn chưa run lần nào thì chọn giá trị return
thứ 3). C’est trop simple :d.
_ Sau khi đến đây, ta cần biết ai trỏ đến địa chỉ này (cụ thể là hàm call nào trỏ đến địa chỉ này,
một trong số đó là magic call). Tại 48180D bạn nhấn Ctrl+R:
_Vậy là có hai đoạn call nằm trong diện nghi vấn. Theo bạn NOP cái nào bây giờ nhỉ? NOP bậy là
đi bụi ngay. Tui cũng chả biết cái nào lun :D. Đùa thoai, bạn còn nhớ địa chỉ return ta vừa tìm
không:
0012BC80 |004814C5 RETURN to UnPackMe.004814C5 from UnPackMe.0048180D
_Thấy 4814C5 có chút liên quan nên ta chọn nó cái rồi tính gì tính! Làm sao mà chọn được vì nó
đã được gọi rồi, cái thằng cần tiêu diệt là 481795. Khó hiểu quá hả, rất đơn giản, giống như cây
súng, cái cò muốn bóp thì phải có đạn, cái băng đạn đóng vai trò trung gian. Thật vậy, giá trị
của 4814C5 chỉ đóng vai trò trung gian để hàm WriteProcessMemory gọi lên. Điểm mấu chốt
nằm ở 481795. Ta cần patch chỗ hàm này. Double click vào
References in UnPackMe:.text1 to 0048180D, item 1
Address=00481795
Disassembly=CALL UnPackMe.0048180D
_Ta đến đây:
_Nop nó:
_Việc cần làm tiếp theo là chúng ta cắt đứt quan hệ giữa father và child bằng cách tạo một lặp
vô tận. Bằng cách nào, Wow, câu hỏi rất hay. Bạn còn nhớ địa chỉ Buffer chứa bytes để patch
vào child không, chúng ta sẽ đi đến entry point của Buffer để dùng opcode Jump EIP làm vòng
lặp vô tận trên EP của buffer này (tức là cho nó jump tới chính nó , jump hoài, jump mãi mãi
cho đến ngàn sau, khà khà). Cái quan trọng là làm sao tìm được EP. Khá đơn giản! Bạn còn nhớ
giá trị tui trừ 4271b0-427000=1b0 không? Cộng giá trị này với địa chỉ Buffer ta tới được EP của
Buffer này để patch. Như thế ta có 1B0+383070= 383220. Ctrl+G đến địa chỉ này để patch, No
no. Không pro tí nào. We are REA, we are pro . Dùng đến Tools của pro đi, yeah! Tui dùng
P.U.P.E. 2005 Suite - Universal Process Patcher.
_Mở Pupe lên, khác với thông thường khi attach ta chọn process không bị red color, nhưng khi
patch pro kiểu này ta cần biết PiD của red color process. Sau khi nhớ PiD, right click tại process
trên Pupe, chọn num of Bytes là 2, nhập vào địa chỉ EP của Buffer, click search, ta cần patch lại
thành EBFE. Chú ý, đây là tools cực mạnh của Game Cracking!
_Lúc này tại địa chỉ 383220 sẽ bị thay đổi theo:
_Lúc này bạn còn một breakpoint tại kernel32 là WriteProcessMemory. Bc nó, sau đó đặt một
breakpoint bp WaitForDebugEvent, F9.Tại địa chỉ 0012BCBC [in Stack] -> right click > Follow in
Disassembler.
_Tại đây, cần set một origin tại đây:
_Ta thấy:
_Ta cần tạo một vùng nhớ để decrypt 1000 bytes và tại 47e8bf chúng ta sẽ trỏ tới vùng nhớ ta
sắp tạo. Mà tạo ở đâu bi giờ nhỉ. Bạn còn nhớ hình địa chỉ 48180D kô, tôi thấy một địa chỉ hấp
dẫn 401000. Ok, khoan tạo, ta jump tới đó cái đã. Cần patch đám code tại đây để chúng chỉ làm
một việc duy nhất là jump đến vùng nhớ của ta. Để jump thành công ta cần làm cỏ sạch đám
code của hàm WaitForDebugEvent. Ta thấy dưới lệnh test eax, eax có một lệnh jump. Tui hay
đùa là Vip Jump. Chúng ta sẽ bắt nó nhảy tới EP vùng nhớ ta sẽ tạo (ở đây tui lấy 401000). OK
chúng ta patch như sau:
_Ok, bay đến 401000 làm việc thoai :d.
_Uh, mà tạo cái gì bi giờ, khửa khửa. Bảo đảm các bạn cũng bay theo tui gòi. Ặc!
_Ở đây có hai cách tạo vùng nhớ, hix. Đó là cách dùng OpenMutexA và cách tui chỉ sau đây Sở
dĩ cách OpenMutexA không dùng được vì tui lười kiếm mutex .
00401000 60 PUSHAD
00401001 9C PUSHFD
00401002 68 C8FB1200 PUSH 12FBC8 ; ASCII "5D4:AA2FD56DE" ***
00401007 33C0 XOR EAX,EAX
00401009 50 PUSH EAX
0040100A 50 PUSH EAX
0040100B E8 B5A6A577 CALL kernel32.CreateMutexA
00401010 9D POPFD
00401011 61 POPAD
00401012 - E9 7A13A677 JMP kernel32.OpenMutexA
00401017 90 NOP
_Địa chỉ 401002 là giá trị mutex của bạn.
_Cách thứ hai là làm theo như sau:
_Bạn còn nhớ chứ, Ok ta có 3 địa chỉ lưu OEP:
0012CDA8 004271B0 UnPackMe.004271B0
0012CDB4 004271B0 UnPackMe.004271B0
0012CDB8 004271B0 UnPackMe.004271B0
_Ta cần một lệnh nhảy ngược lại địa chỉ ta nhảy tới lệnh NOP tại :
0047E8C6 90 NOP
_Ta cũng cần một lệnh nhảy Jump if Equal để nhảy tới lệnh Nop kết thúc khối lệnh này. Ok,
phân tích xong tui patch thành như sau:
_Cũng có một cách patch khác là
ADD DWORD PTR DS:[12CDA8],1000
ADD DWORD PTR DS:[12CDB4],1000
ADD DWORD PTR DS:[12CDB8],1000
CMP DWORD PTR DS:[12CDA8],UnPackMe.0044B000
JNZ UnPackMe. 0047E8C6
NOP
_Giá trị 44B000 ở đâu ra, hãy xem:
_Ở đây target là VC (+VB,ASM, C) nên ta cmp section text, riêng Delphi thì ta so sánh section
CODE.
_Sau khi patch, tiếp tục patch tại 3 địa chỉ chứa OEP:
_Chúng ta patch thành như vậy để làm dấu hiệu MZP:
_Yeah yeah, CopyMemII ôi, em tiêu gòi. Sau khi patch xong như trên bạn Ctrl+G tới địa chỉ
47E8BF đặt một hardware breakpoint tại đây. Nhấn F9 để run:
_Quay lại 401000, chúng ta by pass debug blocker:
_Tại địa chỉ 401025, chúng ta by pass như thường lệ:
_Nhấn F9, bạn sẽ dừng tại HE. Nhấn F8, khi qua khỏi đoạn nop sau hàm Call
DebugActiveProcessStop, tui run quá sợ eax nó không =1 là công toi, hix, yeah, Không hề bằng
0. Ka ka, ặc: Một thông báo crash, chết tui rồi:
_Khà khà, chọc bạn vui thôi, CopyMem chính thức đã đi bụi. Thằng Debug Blocker cũng xách gói
đi theo. Cái thông báo crash là lời chia tay với chúng ta đấy! Khửa khửa. Đừng đóng, kệ nó. Mở
một OllyDBG khác, attach.
_Nếu bạn làm đúng như tui theo các bước trên thì bạn sẽ thấy hai process hiện lên, nếu không
thì xin chia bùn cùng bạn. Làm lại nhé! Ai làm được tới đây, thì tới luôn bác tài .
_F9, F12, Oh, chúng ta đã chặn đứng được quá trình decrypt của father process rồi!
Congratulation! OEP đã được trả về dạng thật của chính nó!
_Tại đây chúng ta dum full.
Phần quan trọng không kém là chúng ta fix IAT.
_Sau khi dump full, hix hix, bản thân tui unpack unpackme này đúng 5 phút. Viết tut mất 2h các
bác ạ. Với lại em viết xong rồi. Bị overwrite em đau quá, nên giờ lười quá, thoai đi uống café cái.
2.30h sáng gòi!
_Đóng hết Olly, khởi động máy cho chắc ăn . Load target lại. By pass process như thường lệ
(dùng cách tui đã post hoặc đơn giản là dùng script).
_Attach, chọn PiD đúng, F9, F12, change bytes EBFE thành 558B.
_Alt+F1: HE GetModuleHandleA. F9 lần thứ nhất:
_F9 lần 2:
_F9 lần 3:
_F9 lần 4:
_F9 lần 5:
_F9 lần 6:
_F9 lần 7:
_F9 lần 8:
_F9 lần 9:
_F9 lần 10:
_F9 lần 11:
_F9 lần 12:
_F9 lần cuối:
_Nhấn Shift+F9 by pass bạn sẽ ở đây:
_Nhấn F8 trace cho tới 77E7ADA6 C2 0400 RETN 4:bạn sẽ tới đoạn code này:
_Như vậy ta có magic jump là 00C4ACF2 /0F84 32010000 JE 00C4AE2A
Patch nó thành Jump 00C4AE2A:
_Alt+M, Memory breakpoint on access:
_Chúng ta tới được OEP đã bị mã hoá. Dùng API Address để xem mã hàm GetModuleHandleA:
_Ok, địa chỉ của hàm là 77E7AD86, quay trở lại OllyDBG, Alt+M, Ctrl+B nhập vào vào địa chỉ
của hàm GetModuleHandleA đảo ngược là 86 AD E7 77
_Ta sẽ dừng ở đây:
_Vào Dump Window, Ctrl+G nhập vào 460000:
_Cuộn xuống tới khi gặp được hàm đầu tiên:
_Vậy IAT Start bắt đầu từ 460818
_Cuộn xuống cho tới hàm cuối cùng:
_Vậy IAT End là 460F24.
_Vậy độ dài IAT= 460F24-460818=70C
_Như vậy ta có kết quá:
OEP: 000271B0
IATRVA: 00060818
IATSize: 0000070C
_Để nguyên OllyDBG, Mở ImportREC lên, chọn process có PiD trùng process con, nhập IAT thử
nhấn IAT Auto Search xem sao:
_Được rồi, nhập thông tin ở trên vào nhấn Get Imports đi:
_Show Invalid, Cut thunks, fix dump:
_Giai đoạn quan trọng nhất: Run dumped_.exe
_ 28 trang cho một dạng protect làm đau đầu các unpacker. Nghĩ cũng đáng chứ, phải không
bạn!
Target#2: Circuit Shop – Armadillo 4.xx
__Bạn tự viết, nếu không được liên hệ trong topic này.
Target#3: SnD Unpackme-Armadillo 4.10a
_Bạn tự viết, nếu không được liên hệ trong topic này.
Target#4: SnD Unpackme-Armadillo 4.20
_Bạn tự viết, nếu không được liên hệ trong topic này.
IV. Conclusion
_Tuần sau tui phải đi xuống Miền Tây khảo sát thị trường gòi (cái này mấy sếp tui bảo nhậu mút
mùa gòi. Khửa khửa khửa) nên tui offline vài tuần. Hẹn tái ngộ quý bà con với Nanomites.
_Tại sao tui không viết nhiều tut mà chỉ viết một, thưa rằng kiểu CopyMem chỉ có một kiểu và
một cách như thế này thôi. Em test gòi, sẽ post expansion của tut sau, bây giờ nó dài quá
không chịu nổi nữa.
_Trong thời gian tui đi, chắc cũng có lên thảo luận với anh em, anh Còm đừng close topic nhé!
_Bà con cô bác nhiều người muốn bít mặt em. Vâng, em post hình em 5 năm về trước cho bà
con xem đỡ ghiền :D. Con bé đứng kế em giờ nó sắp có chồng gòi, bà con đừng hỏi. Tội nghiệp
em . Anh rể con bé này là người anh em tốt của em. Anh em cột chèo mà ;;).
Mỏi gót lê chân khắp đất trời
Mắt xanh dõi hết mấy trùng khơi
Nơi nơi chỉ thấy người múa kiếm
Nào biết tìm đâu kiếm múa người
Kiếm Ma Độc Cô Cầu Bại
GrEeTs Fly Out: Deux, INFINITE, Computer_Angel, Zombie, NVH(c), softcracker_vn, luucorp, Aaron, JMI, Canterwood,
hhphong, R@dier, tlandn, RCA, CTL, Moonbaby, kienmanowar, benina, TQN, the_lighthouse, Nini, hoadongnoi, dqtln, hosiminh,
Nilrem, Teerayoot, Ferrari, Kruger, Kelvin, Devilz, NXL ...and you !
Special Thanx Cracks Latinos.
Merci FFF, RiF, N-Gen (closed), ICI-TEAM pour me-aider des connaissances du Game Cracking!
Thanx the author of OllyDBG.
To be continued...
Written by hacnho (tutorial date: Tien Giang 3/09/2005)
Các file đính kèm theo tài liệu này:
- Armadillo_tut_serie#4.pdf