— Sự kiện do VNSecurity (http://www.vnsecurity.net) tổ chức —

hero

Tiếp nối buổi hội thảo Trà Đá Hacking #01 tại TP Hồ Chí Minh, VNSecurity sẽ tổ chức buổi Trà Đá Hacking số #02 tại Hà Nội vào ngày 16/09/2016.

Ban tổ chức đang tìm kiếm các bài trình bày cho buổi Trà Đá Hacking số #02. Bạn nào muốn đăng ký trình bày tại hội thảo vui lòng gửi bài tại http://goo.gl/forms/zYmm6CdauKQcQpC72.

Update:

Các bạn đã có thể đăng ký tham dự Trà Đá Hacking #02 trên website tại http://trada.vnsecurity.net/#tickets. Nhanh chân đăng ký kẻo hết chỗ nhé.

Như lần Trà Đá Hacking số #01 trước đây, ban tổ chức sẽ tặng một số lượng vé miễn phí lớn cho các trường đại học ở khu vực phía bắc, ưu tiên cho các trường có đội thi CTF. Đại diện các trường vui lòng liên hệ trada@vnsecurity.net để nhận vé miễn phí nhé.

Ban tổ chức vẫn đang tìm kiếm thêm bài trình bày cho buổi Trà Đá Hacking số #02. Bạn nào muốn đăng ký trình bày tại hội thảo vui lòng gửi bài tại http://goo.gl/forms/zYmm6CdauKQcQpC72.

Chi tiết tại: https://www.facebook.com/vnsec/

Regards,


19/05/2015, tôi hoàn thành OllyDbg_tut27, 17/07/2016 đặt tay lên bàn phím và hoàn thành OllyDbg_Tut28 waaaht. Hơn 1 năm tôi mới có thời gian để lại viết tiếp tục những thứ còn đang dang dở, kiểu như người ta viết thơ tình mà đang nghĩ thì tụt mịa nó cảm xúc … đành phải đợi lúc nào đó cảm xúc nó hồi sinh adore. Mà cứ đợi như thế, rồi đợi mãi, rồi tôi đọc Blog của Yêuchimsẻ (http://blog.yeuchimse.com/) có đoạn “Thời gian chẳng bao giờ dừng lại, mới đó mà cũng đã được một năm.” Cuộc sống, công việc nhiều khi cứ cuốn tôi rời xa khỏi đam mê, đôi khi không phải vì thời gian eo hẹp, mà vì viết lách là một nghệ thuật, nhiều khi mở máy lên định viết nhưng rồi nghĩ một hồi tôi đếch nghĩ ra nổi phải mở đầu như thế nào chứ chưa nói tới viết về phần kỹ thuật, thế nên mỗi lần định viết lại là một lần tôi thở dài, đóng máy đi làm việc khác boss. Có thể sẽ có nhiều bạn đọc đọc các bài viết của tôi, rồi tự đặt câu hỏi “Sao ông này cứ viết mãi những thứ đơn giản, cơ bản mà ai cũng biết?”. Trong thế giới quan của tôi, những thứ cơ bản mà chưa làm được thì nói gì đến những điều cao siêu doubt, ngày trước tôi đã không đi từ những thứ cơ bản, nên bây giờ tôi coi mỗi lần viết là một lần tôi học lại.

Lâu lắm rồi tôi mới lại mở đầu bài viết một cách lâm ly, bi đát như thế này, quay trở lại nội dung chính, phần 28 này sẽ là tiếp tục của phần 27 cách đây hơn 1 năm có lẻ. Có lẽ, tôi có thể khẳng định với các bạn rằng, đây là siêu phẩm về unpack UPX đỉnh cao nhất trong suốt sự nghiệp viết lách của tôi, chưa bao giờ các bạn tưởng tượng lại có một bài viết nào về unpack UPX dài đến thế…. after_boom, viết xong thực sự tôi cũng cạn lời!!!hell-yes-onion-head-emoticon

Link download toàn bộ bài viết:

https://mega.nz/#!SgthVZKI!kOU1NRkgrggF2FayK-970VcG8X7BHnNPH65CtPZ2yo0

Regards,

2016-04-21_18-33-26


Contributed By Check Point Software Technologies LTD.

Features

1. Seamless synchronization of labels, function names, comments and global variables (w/wo demangling)

  • Synchronization modes
    • On demand
    • On rename (update on-the-fly)
  • Supports image base-independent synchronization

2. Dynamic dumping of debugged process memory regions

It can be useful in the following cases:

  • When debugged process has extracted/temporary/injected module which doesn’t appear in modules list
  • When it doesn’t have a valid PE header
  • When it have corrupted import table, etc.

3. Python scripting

We support the following list of debug backends for now:

Latest release: v_1_1_0_3

[-] anti-dubug: removed hardcoded classname/window name
[*] OllyDbg20: updated SWIG SDK-wrapper compatibility with win types
[*] dbg backends FIX: fixed trucation of RPC request
[*] dbg backends FIX: now we send packet length for each RPC call for additional message check


Author: Neutrino (CLS)

OllyDBG v1:

Tips sobre BreakPoint Condicional Log en Ollydbg1.10

Fig. 1

OllyDBG v2:

Tips y metodo sobre BreakPoint Condicional Log en Ollydbg2.01

Fig. 2

OllyDbg v2

Posted: May 13, 2016 in OllyDBG v2
Tags: ,

I wan to share my OllyDbg v2 (shared by Vic) that i used for my RCE hobby🙂.

m4n0w4r

Download here:

https://goo.gl/HonQG0

Regards,

m4n0w4r


Viết linh tinh ……too_sad

Cơ bản, nhiều người có cùng suy nghĩ chung là không sử dụng IDA trong việc unpack file và theo tôi quan điểm này không có gì sai, vì như đã biết việc unpack thường sử dụng các trình debugger như OllyDBG/Immunity kết hợp với các công cụ fix PE file (LordPE; ImpREC, Scylla…). Tuy nhiên, trong bài viết này chúng ta sẽ thử dùng IDA để unpack một unpackme đơn giản, không sử dụng các biện pháp bảo vệ cao cấp, mục đích chủ yếu là để biết được cách thức thực hiện như thế nào với IDA.

Công cụ sử dụng:

  • DIE v1.01 (Detect It Easy)
  • IDA 6.8
  • Peditor v1.7 (yoda&M.o.D)
  • Scylla v0.9.8

Tải Unpackme tại: https://www.hex-rays.com/products/ida/support/tutorials/unpack_pe/test00.exe

Trước tiên, dùng DIE để kiểm tra sơ bộ unpackme:

2016-04-16_16-15-00

Fig.1

File được pack bằng MEW(SE v1.0), đoán là bản Standard Edition. Gồm 2 sections, section đầu có tên là MEW và section thứ hai có tên rất loằng ngoằng:

2016-04-16_16-18-47

Fig.2

Thông tin về các hàm APIs được unpackme sử dụng:

2016-04-16_16-20-04

Fig.3

OK thông tin cơ bản đã có. Tiếp theo mở IDA và load unpackme:

2016-04-16_16-05-50

Fig.4

Giữ nguyên các tùy chọn mặc định tại phần Options, nhấn OK để tiếp tục, ta nhận được thông báo sau:

2016-04-16_16-11-15

Fig.5

Thông báo này cho biết, section có ký tự loằng ngoằng bên dưới section MEW đã bị cắt bỏ các offsets và IDA sẽ chỉ đọc 0x7A1 bytes. Bỏ qua cảnh báo này, nhấn OK để tiếp tục, một thông báo nữa xuất hiện cho biết import của file đã bị hủy, điều này có nghĩa là khả năng lớn là file đã bị pack hoặc đã bị chỉnh sửa khiến cho việc phân tích trở nên khó khăn:

2016-04-16_16-25-47

Fig.6

Nhấn OK, để tiếp tục, IDA sẽ dừng lại tại đây:

2016-04-16_16-32-25

Fig.7

Quan sát tại màn hình IDA, lúc này ta thấy trước các byte đều xuất hiện cụm “dd” hay “db”. Điều này có nghĩa là IDA không nhận diện được code nên nó diễn giải dữ liệu dưới dạng dword (dd), word(dw), byte(db). IDA cho phép chúng ta thay đổi kiểu dữ liệu bằng cách nhấn phím tắt D:

2016-04-16_16-50-10

Fig.8

Để cấu hình các kiểu dữ liệu chọn Options > Setup data types… hoặc nhấn Alt+D:

2016-04-16_16-52-43

Fig.9

Đây là các thiết lập mặc định của IDA để chuyển đổi giữa các kiểu byte, word và dword khi nhấn D, tuy nhiên ta cũng có thể cấu hình thêm các loại dữ liệu khác nếu cần thiết. Trong trường hợp này của unpackme, ta cần không thực hiện việc thay đổi kiểu dữ liệu nữa mà thực hiện chuyển đổi các dữ liệu này sang các lệnh assembly. Để thực hiện việc chuyển đổi này, IDA hỗ trợ phím tắt C hoặc vào Edit > Code:

2016-04-16_17-11-40

Fig.10

Kết quả có được như sau:

2016-04-16_17-13-25

Fig.11

Ta thấy rằng, dữ liệu đã được chuyển thành một lệnh nhảy tới địa chỉ thuộc section đầu tiên, bắt đầu từ 400000 và kết thúc tại 401000. Vì IDA đã không nhận diện được code chuẩn ngay từ đầu nên lệnh nhảy này cũng không cho ta nhiều thông tin, chọn địa chỉ 400158 và nhấn Enter để follow cũng không tới được địa chỉ đó. Nếu như chúng ta sử dụng trình debugger như OllyDBG thì hoàn toàn có thể tới được địa chỉ trên:

2016-04-16_17-28-16

Fig.12

Tuy nhiên, mục tiêu của bài viết là sử dụng IDA để thực hiện nên ta sẽ làm theo cách khác. Ta sẽ thay đổi cách load file với tùy chọn Manual load như đã thấy trong phần Options của IDA. Mở lại unpackme, lựa chọn như hình minh họa:

2016-04-16_17-35-49

Fig.13

Tùy chọn Manual load cho phép ta quyết định sections nào sẽ được load vào IDA thay vì để IDA tự động load toàn bộ, việc bỏ tùy chọn Create imports segment sẽ loại bỏ cảnh báo của IDA về việc IAT bị hủy. Sau khi cấu hình như trên, nhấn OK để tiếp tục:

2016-04-16_17-42-20

Fig.14

IDA yêu cầu nhập địa chỉ của ImageBase. Ta giữ nguyên không thay đổi, nhấn OK để tiếp tục, IDA sẽ yêu cầu xác nhận việc nạp các sections và file header:

2016-04-16_17-44-24

Fig.15

2016-04-16_17-44-24

Fig.16

2016-04-16_17-46-15

Fig.17

Nhấn Yes để xác nhận, sau khi IDA load xong, nhấn C để chuyển dữ liệu sang code:

2016-04-16_17-54-27

Fig.18

Như đã thấy trên hình, địa chỉ 400158 đã được IDA nhận dạng là một location cụ thể, nhấn đúp chuột vào địa chỉ này ta tới vùng code bắt đầu tại địa chỉ đó:

2016-04-16_17-57-47

Fig.19

Tại đây được IDA nhận là Header code, nhấn P để tạo function hoặc chọn Edit > Functions > Create function…

2016-04-16_20-06-06

Fig.20

Nhấn space bar để chuyển sang Graphic mode. Quan sát tại màn hình Graphic ta thấy có rất nhiều lệnh call và lệnh nhảy, các lệnh call đều liên quan đến thanh ghi ebx. Thanh ghi ebx được khởi tạo bởi hai lệnh mov esi, 40601Ch & mov ebx, esi:

2016-04-16_20-19-37

Fig.21

Quan sát giá trị tại 0x40601C xem có thông tin gì:

2016-04-16_20-23-40

Fig.22

Nhấn D để chuyển đổi kiểu dữ liệu về giá trị dword:

2016-04-16_20-25-34

Fig.23

Chuyển tới địa chỉ 0x400130, quan sát tại đây có thể thấy rằng vùng code thể hiện thông tin của các sections tương ứng với thông tin mà ta thấy được khi xem bằng DIE:

2016-04-16_20-36-44

Fig.24

Tên của section thứ nhất (“MEW”) thì rõ ràng rồi, nhưng tên của section thứ hai thì nhìn rối rắm và dường như nó đã được encrypt hoặc có thể chứa thông tin gì đó. Chọn tên section này và thử nhấn C để chuyển sang mã lệnh, ta thấy có lệnh được ẩn trong chuỗi tên:

2016-04-16_20-46-51

Fig.25

Ta thấy có hai lệnh nhảy tới hai địa chỉ là 400108+7 và 400108+4, các địa chỉ này đều nằm giữa chuỗi tên của section thứ nhất, để có thông tin cụ thể về các địa chỉ này ta cần phải undefine vùng địa chỉ chứa tên của section thứ nhất. Chọn địa chỉ 0x400108 và nhấn phím U:

2016-04-16_21-05-16

Fig.26

Sau khi undefine, ta thấy tên của section thứ nhất chính xác chỉ từ 0x400108 đến 0x40010B, còn các vùng từ 0x40010C tới 0x40010F là vùng dữ liệu được IDA đánh dấu là unk (unknown). Để chỉnh sửa lại cho chính xác, nhấn C để chuyển đổi vùng đó thành code:

2016-04-16_21-19-48

Fig.27

Sau khi chuyển đổi thành công thì đoạn code tại 0x400130 cũng thay đổi theo:

2016-04-16_21-23-31

Fig.28

Thông tin thu được khá hữu ích rồi, tuy nhiên để tiếp tục ta phải sử dụng tới việc debug. Lựa chọn trình debugger như hình:

2016-04-16_21-32-57

Fig.29

Quay lại lệnh nhảy tới sub_400158, nhấn F2 để đặt một breakpoint:

2016-04-16_21-34-46

Fig.30

Sau khi đặt bp xong, nhấn F9 để run unpackme, ta sẽ dừng lại tại bp:

2016-04-16_21-40-13

Fig.31

Nhấn F7 để trace tới sub_400158:

2016-04-16_21-41-43

Fig.32

2016-04-16_21-43-10

Fig.33

Tại màn hình debug của IDA, nhấn Shift+F7 để mở cửa sổ Segments. Quan sát tại cửa sổ này ta thấy thông tin về các sections của file. Thông thường, dưới thông tin về PE header sẽ là section .text (ở đây có thể là section MEW(đã bị packer đổi tên)):

2016-04-16_22-01-59

Fig.34

Theo thông tin cửa sổ Segments cung cấp thì section MEW bắt đầu từ 0x401000 và kết thúc tại 0x406000, vậy size của section này là 0x5000. Tiếp theo, mở cửa sổ Breakpoint lists (Ctrl+Alt+B) để thiết lập một bp tương tự như ta đặt memory bp trong OllyDBG. Tại cửa sổ Breakpoints, nhấn Ins để thiết lập thêm một bp như sau:

2016-04-17_1-24-04

Fig.35

Với thông tin như trên, ta sẽ thiết lập một bp tại section đầu tiên (thường là section chứa OEP), nơi mà code sẽ được ghi vào để xem code được decompress tại section đó như thế nào. Ở đây ta chọn section MEW tại 0x401000 và kích thước là 0x5000 để yêu cầu dừng lại khi đạt tới kích thước đã thiết lập. Sau khi đặt xong, nhấn F9 để thực thi:

2016-04-16_22-28-09

Fig.36

Sau khi dừng lại tại bp, ta thấy code đã được decompress xong. Bước tiếp theo ta sẽ tiến hành dump toàn bộ file. Dựa trên thông tin từ màn hình Segments cung cấp, ta sẽ dump file bắt đầu từ 0x400000 tới 0x407004. Để dump được ta sử dụng idc script sau:

static main()
{
auto fp, ea;
fp = fopen("test00_dump.bin", "wb");
for ( ea=0x400000; ea < 0x407004; ea++ )
  fputc(Byte(ea), fp);
}

Tại IDA, nhấn Shift+F2 để mở cửa sổ thực thi script, copy&paste đoạn script trên vào, sau đó nhấn Run để thực hiện:

2016-04-17_1-36-22

Fig.37

Kết quả, ta có file được dump ra là test00_dump.bin nằm cùng thư mục của unpackme:

2016-04-17_1-40-01

Fig.38

Sử dụng PEditor để mở file vừa được dump:

2016-04-17_1-42-02

Fig.39

Nhấn sections để xem thông tin về các section, chuột phải tại section MEW và chọn:

2016-04-17_1-44-59

Fig.40

Sau khi dump xong, đổi .bin thành .exe:

2016-04-17_1-48-53

Fig.41

Bước cuối cùng của quá trình unpack chính là fix IAT. Mở Scylla và chọn process test00.exe. Chỉnh lại OEP thành 0x401000, sau đó nhấn IAT Autosearch:

2016-04-17_1-53-28

Fig.42

OK Scylla đã tìm thấy thông tin của IAT, tiếp theo nhấn Get Imports để nhận các APIs:

2016-04-17_1-56-59

Fig.43

Tìm thấy 19 hàm APIs mà unpackme sử dụng, không có invalid. Nhấn Fix Dump để thực hiện fix cho file test00_dump.exe:

IDA_19funcs

Fig.44

OK, vậy là quá trình rebuild thành công, Scylla tạo ra file mới là test00_dump_SCY.exe. Chạy file đã fix kết quả như sau:

2016-04-17_2-02-57

Fig.45

Vậy là quá trình unpack đã thành công!!

2016-04-21_18-33-26


1.1. First solution

Rule in Readme.txt:

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
AuthKey = un_md5(DecryptKey) + " " + un_md5(EXE's Key)
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Ex:)
 DecryptKey = 1dfb6b98aef3416e03d50fd2fb525600
 EXE's  Key = c944634550c698febdd9c868db908d9d
 => AuthKey = visual studio
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Scan this target by ExeInfo PE:

Krchal131

Figure 1

We have “AutoHotkey v1.0.48.05 – AutoIt3 v2.x.x” and ExeInfo recommend us use Exe2Aut to Unpack/Decompile this target. Ok, let’s try to use ExeInfo and here is the result:

Krchal132

Figure 2

Open _myExeToAut.log in the same directory, we will have the first MD5 key “220226394582d7117410e3c021748c2a

================================================================================
-=  myExe2Aut >The Open Source Autoit/AutoHotKey Script Decompiler< 1.92 build(54) =- ================================================================================ Unpacking: C:\Documents and Settings\manowar\Desktop\Reversing.kr\Chal13\ahk.exe AU3_Signature: A3 48 4B BE 98 6C 4A A9 99 4C 53 0A 86 D6 48 7D £HK¾˜lJ©™LS †ÖH} Script Type 3.0 found. 00032813 -> SubType: 0x03   áú
~ Note:  The following offset values are were the data ends (and not were it starts) ~
Script is password protected!
00032834 -> Password/MD5PassphraseHash: 3232303232363339343538326437313137343130653363303231373438633261
            220226394582d7117410e3c021748c2a
MD5PassphraseHash_ByteSum: 0000075D  '+ 22AF' => decryption key!

Open another file is ahk.ahk, we get the second key “54593f6b9413fc4ff2b4dec2da337806”:

;<COMPILER: v1.0.48.5>
inputbox,pwd
if (pwd== "54593f6b9413fc4ff2b4dec2da337806"){
MsgBox
}

Open https://hashkiller.co.uk/md5-decrypter.aspx to decrypt above MD5 keys:

Krchal133

Figure 3

Krchal134

Figure 4

Finally, the right Flag is: isolated pawn

1.2. Second solution

Scan this target by RDG Packer Detector:

Krchal135

Figure 5

RDG shows this target is packed by UPX. Let’s try to use UPX to unpack:

Krchal136

Figure 6

Run unpacked file, we get the error messages:

Krchal137

Figure 7

Let’s open OllyDBG and load packed file, scroll down and put BP at “00471BD9 ^\E9 710FFDFF     jmp     ahk.00442B4F” to manual unpack it:

Krchal138

Figure 8

F9 to run, we stop at BP. F8 to trace over, we stop here:

Krchal139

Figure 9

Search all referenced text strings to find “EXE corrupted”:

Krchal1310

Figure 10

Double click on the ASCII “EXE corrupted“, we go to the following address: 0x00448273. Scroll up, we can see the jump that will bypass the error message at “00448265 |. /74 16 je short ahk.0044827D”. So we need to place a breakpoint at the call before this jump:

Krchal1311

Figure 11

Then press F9, we’ll stop at bp. Press F7 to trace into this call, then F8 to trace over, the routine will show us the address that store the decryption key:

Krchal1312

Figure 12

After finish the call at “0044825E |. E8 64860000 call ahk.004508C7 ; \ahk.004508C7”, we back to the jump that will bypass the the error message at “00448273 |. 68 34E34500   push   ahk.0045E334 ; ASCII "EXE corrupted"” and stop here:

Krchal1313

Figure 13

This routine will decompile the file with the decryption key above. After trace over the call at address “00448293 |. E8 078A0000   call   ahk.00450C9F ; \ahk.00450C9F” and follow in dump the address at ECX register, we’ll have the exe’s key:

Krchal1314

Figure 14

Finally, visit https://hashkiller.co.uk/md5-decrypter.aspx to decrypt above keys that we get!

End.


The content of Readme.txt file: Twist1.exe is run in x86 windows.

Run Twist1.exe and input fake flag:

Krchal121

Figure 1

Let’s open the target in OllyDBG, search all referenced text strings, we have nothing useful information:

Krchal122

Figure 2

Maybe all strings are encrypted and will be decrypt at runtime. Press F9 to run and search again:

Krchal123

Figure 3

Double-click on the “ASCII “Correct!”,LF”, scroll up and set HWBP on Execute at 00401270   E8 EBFEFFFF call   <Twist1.Nop_call>

Krchal124

Figure 4

Restart OllyDBG and press F9 again, we will break at bp. Trace over these calls like the figure bellow and input the fake flag:

Krchal125

Figure 5

After input fake flag and press enter, we will back to OllyDBG. Then trace into this call:

004012C6       E8 75FFFFFF             call   Twist1.00401240

Krchal126

Figure 6

The input flag will be saved to another location, like this:

Krchal127

Figure 7

After the above loop, the unconditional jump will to 0040720D. At 0040720D, the routine will set some values to 00409150 address. If change these value to disassemble, we have this code:

00409150    B8 9A000000     mov     eax, 0x9A
00409155    BA 0003FE7F     mov     edx, 0x7FFE0300
0040915A    FF12            call    dword ptr [edx]
0040915C  - E9 D41FA400     jmp     00E4B135

At 00407294 address, we see the call to this address: call Twist1.00409150. This call will make debug is crashed. So need some tricks to bypass this call and unconditional jump, we will stop at 004072CF /E9 5C010000 jmp Twist1.00407430:

Krchal128

Figure 8

Continue to bypass some calls and checks that make crash when debug:

Krchal129

Figure 9

We go to the routine that take the seventh character of InputFlag to bl, xor bl with 0x36 and save to ds:[0040C450]:

Krchal1210

Figure 10

Then the value at [0040C450] will be compared with 0x36, if not equal will exit routine. So we know that the seventh character of InputFlag must be null value and the length of InputFlag is six:

Krchal1211

Figure 11

Next, we will see the validation code for each characters of InputFlag.

  • 1st character:
0040760D     33C0             xor     eax, eax       ; eax = 0
0040760F     A0 90B94000     mov     al, byte ptr [0x40B990]; al = InputFlag[0] (1st char of InputFlag)
00407614     E8 12000000      call    Twist1.0040762B
0040762B     33D2             xor     edx, edx       ; edx = 0
0040762D     C0C8 06          ror     al, 0x6        ; rotate 6 bits right in al
00407630     A2 00B04000      mov     byte ptr [0x40B000], al      ; save al to [0040B000]
00407700     8A0D 00B04000    mov     cl, byte ptr [0x40B000]   ; cl = [0040B000]
004076D0     80F9 49          cmp     cl, 0x49                  ; cl = 0x49?
004076D3     0F85 2C020000    jnz     &lt;Twist1.exit_routine&gt;

The following pseudo code:

InputFlag[0] ror 0x6 = 0x49 -&gt; InputFlag[0] = 0x49 rol 0x6 = 0x52 (‘R’)
  • 3rd character:
00407750     880D E0CC4000    mov     byte ptr [0x40CCE0], cl  ; [0x40CCE0] = InputFlag[2]
0040777D     33C0             xor     eax, eax              ; eax = 0
0040777F     8BC8             mov     ecx, eax              ; ecx = 0
00407781     8BD0             mov     edx, eax              ; edx = 0
00407783     A0 E0CC4000      mov     al, byte ptr [0x40CCE0] ; al = InputFlag[2] (2nd char of InputFlag)
00407788     34 77            xor     al, 0x77    ; al = al ^ 0x77
004077A3     3C 35            cmp     al, 0x35    ; al = 0x35?
004077A5     75 59            jnz     short &lt;Twist1.exit_routine&gt;

The following pseudo code:

InputFlag[2] ^ 0x77 = 0x35 -&gt; InputFlag[2] = 0x35 ^ 0x77 = 0x42 (‘B’)
  • 2nd character:
0040780C     8B0D 80CD4000    mov     ecx, dword ptr [0x40CD80]   ; ecx = InputFlag[1]
004077AC     80F1 20          xor     cl, 0x20                    ; cl = cl ^ 0x20
004077C5     80F9 69          cmp     cl, 0x69                    ; cl = 0x69?
004077C8   ^ 75 F0            jnz     short Twist1.004077BA

The following pseudo code:

InputFlag[1] ^ 0x20 = 0x69 -> InputFlag[1] = 0x69 ^ 0x20 = 0x49 (‘I’)
  • 4th character:
00407838     33C0             xor     eax, eax          ; eax = 0
0040783A     33C9             xor     ecx, ecx          ; ecx = 0
0040783C     33D2             xor     edx, edx          ; edx = 0
0040783E     8A15 F4CC4000    mov     dl, byte ptr [0x40CCF4]   ; dl = InputFlag[3]
00407844     8AC2             mov     al, dl            ; al = dl
00407846     A2 00C44000      mov     byte ptr [0x40C400], al   ; [0040C400]=al
00407829     8A15 00C44000    mov     dl, byte ptr [0x40C400]
0040790E     8A15 01C44000    mov     dl, byte ptr [0x40C401]   ; dl = InputFlag[3]
00407914     80F2 21          xor     dl, 0x21          ; dl = dl ^ 0x21
00407917     C3               retn
00407918     80FA 64          cmp     dl, 0x64          ; dl = 0x64?
0040791B     0F84 AD040000    je      Twist1.00407DCE

The following pseudo code:

InputFlag[3] ^ 0x21 = 0x64 -> InputFlag[3] = 0x64 ^ 0x21 = 0x45 (‘E’)
  • 5th character:
004077D1     8B15 F0CC4000    mov     edx, dword ptr [0x40CCF0]  ; edx = InputFlag[4]
004077D7     8915 30CD4000    mov     dword ptr [0x40CD30], edx  ; ds:[0040CD30]=edx
00407DCE     8A15 30CD4000    mov     dl, byte ptr [0x40CD30]    ; dl = InputFlag[4]
00407E02     80F2 46          xor     dl, 0x46                   ; dl = dl ^ 0x46
00407E19     58               pop     eax
00407E1A     3C 08            cmp     al, 0x8
00407E1C    /75 02            jnz     short Twist1.00407E20

The following pseudo code:

InputFlag[4] ^ 0x46 = 0x8 -> InputFlag[4] = 0x8 ^ 0x46 = 4E (‘N’)
  • 6th character:
0040778C     8A0D E4CC4000    mov     cl, byte ptr [0x40CCE4]      ; cl = InputFlag[5]
00407792     880D F4CF4000    mov     byte ptr [0x40CFF4], cl
004078A6     C005 F4CF4000 04 rol     byte ptr [0x40CFF4], 0x4     ; rotate 4 bits left (0x40CFF4 contains 5th char of InputFlag)
00407F77     8A15 F4CF4000    mov     dl, byte ptr [0x40CFF4]
00407F7D     C605 777F4000 FD mov     byte ptr [0x407F77], 0xFD
00407F84     80FA 14          cmp     dl, 0x14                    ; dl = 0x14?
00407F87     75 36            jnz     short Twist1.00407FBF

The following pseudo code:

InputFlag[5] rol 0x4 = 0x14 -> InputFlag[5] = 0x14 ror 0x4 = 0x41 (‘A’)

Finally, we have the correct flag is : “RIBENA”.

End.


Run FPS.exe, we will start the game with a gun:

Krchal111

Figure 1

Use direction key to move character, we will see the strange doll. They can not die if we shoot them. The game will end if we touch them🙂.

Krchal112

Figure 2

Let’s use IDA and OllyDBG combination to analyse target. In OllyDBG, search all referenced text strings, we find the “Game Clear” string:

Krchal113

Figure 3

Double clicking on this string will bring us to the routine:

Krchal114

Figure 4

In IDA we have:

Krchal115

Figure 5

With this information, we can see that the text in message box is encrypted. So we need to decrypt this string. Follow in Dump in OllyDBG:

Krchal116

Figure 6

In IDA, select this text and press “X” to find another routine references to it.

Krchal117

Figure 7

Double clicking on sub_403400+2D:

Krchal118

Figure 8

This routine will be used to decrypt the text of message box. First, we see that the eax register is used as index of encrypted string, I named it is Msg_text. Value of eax is set by the call sub_403440, so that eax will have values in range [0…52], ecx = eax * 0x210. Ecx register is used as specific offset to set value to cl, then use xor to decrypt: Msg_txt[eax] = Msg_txt[eax] ^ cl. This is the pseudo-code for the snippet:

unsigned int sub_403400()
{
unsigned int i; // eax@1
unsigned int j; // ecx@2
int v2; // edx@2

i = sub_403440();
if ( i != 0xFFFFFFFF )
{
	j = 0x84 * i;
	v2 = dword_409190[0x84 * i];
	if ( v2 &gt; 0 )
	{
		dword_409190[j] = v2 - 2;
	}
	else
	{
		dword_409194[j] = 0;
		Msg_text[i] ^= byte_409184[j * 4];
	}
}
return i;
}

Try to set bp and debug in OllyDBG, we know cl register will have value is 0x0, 0x4, 0x8, 0xC,…

Krchal119

Figure 9

Here is the code to find the Flag:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    unsigned char encrypted_str[52]={0x43, 0x6B, 0x66, 0x6B, 0x62, 0x75, 0x6C, 0x69, 0x4C, 0x45, 0x5C, 0x45, 0x5F, 0x5A, 0x46, 0x1C, 0x07, 0x25, 0x25, 0x29, 0x70, 0x17, 0x34, 0x39, 0x01, 0x16, 0x49, 0x4C, 0x20, 0x15, 0x0B, 0x0F, 0xF7, 0xEB, 0xFA, 0xE8, 0xB0, 0xFD, 0xEB, 0xBC, 0xF4, 0xCC, 0xDA, 0x9F, 0xF5, 0xF0, 0xE8, 0xCE, 0xF0, 0xA9, 0x00};
    unsigned char flag[100]={0};
    int i=0;

    for (i=0; encrypted_str[i]!=0;i++)
    {
        flag[i] = encrypted_str[i] ^ (i*4);
    }
    flag[i] = '\x00';

    printf("The right flag is: %s", flag);
    return 0;
}
Krchal1110

Figure 10

End.


Use any PE Detector to quickly scan target:

Krchal101

Figure 1

Okay, it’s a .NET exe file. Run file to get information:

Krchal102

Figure 2

Huh, it displays a bank form😦. Let’s open target in dnSpy:

Krchal103

Figure 3

Right click to CSHOP and select “Go to Entry Point”:

Krchal104

Figure 4

Click FrmMain, we go here:

Krchal105

Figure 5

Follow InitializeComponent() function we’ll see two EventHandlers are _Click and Form1_Load:

Krchal106

Figure 6

Krchal107

Figure 7

Look at Form1_Load, this routine sets all labels to empty:

Krchal108

Figure 8

Look at _Click, this routine sets each labels with one default character:

Krchal109

Figure 9

With the information above, we have string: W54RE6MIPSP6S. Try to use this string to authenticate at reversing.kr, we will get fail. Back to the top of InitializeComponent() to dig deeper:

this.\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD = new Button();
this.\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD.Location = new Point(165, 62); <- Set location of new button
this.\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD.Name = "btnStart"; <- Set button’s name
this.\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD.Size = new Size(0, 0); <- Set button’s size
this.\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD.TabIndex = 0;
this.\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD.UseVisualStyleBackColor = true;
this.\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD.Click += new EventHandler(this.\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD_Click);

A notable point in above code that sets the size of button to zero. Let’s use dnSpy to changes these values to (40, 40) like the picture bellow:

Krchal1010

Figure 10

After change, save to new file (ex: CSHOP_Patched.exe). Execute the patched file, we’ll see the button, click it to get the key:

Krchal1011

Figure 11

End.


Rule: Decrypt File (EXE)

Run target to get basic information:

Krchal91

Figure 1

Let’s open the target in OllyDBG, search all referenced text strings, we’ll get like this:

Krchal92

Figure 2

Follow 0x0044A775 address and set BP at 0044A792 |. FF15 B8C04400 call dword ptr [<&MSVCR100.scanf>]; \scanf:

Krchal93

Figure 3

Press F9 to run and input any key you like, then press enter, we’ll back to OllyDBG:

Krchal94

Figure 4

After target gets the input key, next it calculates the input key length:

Krchal95

Figure 5

Next, it opens the file whose name is specified in the parameter filename and mode is rb (read, binary file):

Krchal96

Figure 6

This target opens file that named file in the same directory to read in binary mode, then gets character from stream and stores to the buffer at 0x5415B8 address:

Krchal97

Figure 7

Compare values store at the buffer with the file content is opened with WinHex, we have the same values:

Krchal98

Figure 8

Next, we will see the snippet that use the input key to decrypt the values are stored at the 0x5415B8 address. Let’s see how decryption routine performs:

Krchal99

Figure 9

This is the pseudo-code for the snippet:

For (i=0; i< sizeof(file); i++)
{
	FileContent[i] = FileContent[i] ^ InputKey[i] ^ 0xFF;
}

The decryption result:

Krchal910

Figure 10

Next, reopen file in write mode:

Krchal911

Figure 11

The next snippet takes each value from the buffer and writes back to file:

Krchal912

Figure 12

Content of file after write back:

Krchal913

Figure 13

Because the rule of this challenge is Decrypt File (EXE), so we know that the file after decrypt will be a normal exe file. As we know, the normal exe file has the valid PE header same as the picture bellow:

Krchal914

Figure 14

We also have the decryption algorithm in the previous analysis: FileContent[i] = FileContent[i] ^ InputKey[i] ^ 0xFF; so FileContent[i] must equal 0x4D, 0x5A, 0x90, etc. To find the InputKey we only need to do: ValidPEHeader[i] ^ FileContent[i] ^ 0xFF = InputKey[i]. Summarize we have calculation table like this:

Validheader[i] operator Filecontent[i] operator default value inputkey[i]
0x4D ^ 0xDE ^ 0xFF 0x6C (l)
0x5A ^ 0xC0 ^ 0xFF 0x65 (e)
0x90 ^ 0x1B ^ 0xFF 0x74 (t)
0x00 ^ 0x8C ^ 0xFF 0x73 (s)
0x03 ^ 0x8C ^ 0xFF 0x70 (p)
0x00 ^ 0x93 ^ 0xFF 0x6C (l)
0x00 ^ 0x9E ^ 0xFF 0x61 (a)
0x00 ^ 0x86 ^ 0xFF 0x79 (y)
0x04 ^ 0x98 ^ 0xFF 0x63 (c)
0x00 ^ 0x97 ^ 0xFF 0x68 (h)
0x00 ^ 0x9A ^ 0xFF 0x65 (e)
0x00 ^ 0x8C ^ 0xFF 0x73 (s)
0xFF ^ 0x73 ^ 0xFF 0x73 (s)
0xFF ^ 0x6C ^ 0xFF 0x6C (l)
0x00 ^ 0x9A ^ 0xFF 0x65 (e)
0x00 ^ 0x8B ^ 0xFF 0x74 (t)

Code in C:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    unsigned int valid_PE[16] = {0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00};
    unsigned int encrypted_PE[16] = {0xDE, 0xC0, 0x1B, 0x8C, 0x8C, 0x93, 0x9E, 0x86, 0x98, 0x97, 0x9A, 0x8C, 0x73, 0x6C, 0x9A, 0x8B};
    unsigned int defVal = 0xFF, i = 0;
    unsigned char key[16] = {0};

    for (i=0; i<16; i++)
    {
        key[i] = valid_PE[i] ^ encrypted_PE[i] ^ defVal;
    }

    printf("The decrypt key is: %s \n", key);
    return 0;
}

Okay, we have the decrypt key is: letsplaychess. Run program and input key we will have the decrypt file. Let’s rename file to add the exe extension. Use RDG Packer Detector to check file:

Krchal915

Figure 15

Ohhh, it’s packed by UPX. Using UPX to unpack file:

Krchal916

Figure 16

After unpack successful, run file to get the key:

Krchal917

Figure 17

End.


Load target to IDA and analyze, we’ll find the function that check the Input Serial. With the help of HexRays, we get the following pseudo code:

int check_Input()
{
  int result; // eax@2

  if ( szInput[1] == '1' )
  {
    szInput[0] ^= 0x34u;
    szInput[2] ^= 0x32u;
    szInput[3] ^= 0x88u;
    if ( szInput[4] == 'X' )
    {
      if ( szInput[5] )
      {
        result = 0;
      }
      else if ( szInput[2] == 0x7C )
      {
        if ( szInput[0] == 0x78 )
          result = szInput[3] == 0xDDu;
        else
          result = 0;
      }
      else
      {
        result = 0;
      }
    }
    else
    {
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

With the code above, we can identify the Input serial as follows:

szInput[0] ^= 0x34u == 0x78 --> szInput[0] = 0x78 ^ 0x34 = 0x4C = L
szInput[1] == '1' --> szInput[1] = 1
szInput[2] ^= 0x32u == 0x7C --> szInput[2] = 0x7C ^ 0x32 = 0x4E = N
szInput[3] = ^= 0x88u == 0xDDu --> szInput[3] = 0xDD ^ 0x88 = 0x55 = U
szInput[4] == 'X' --> szInput[4] = X

Finally, we have the key is: L1NUX

End.


Rule: Find the Name when the Serial is 76876-77776. This problem has several answers. Password is ***p

Krchal71

Figure 1

Scan this target with DIE (a PE detector), we have info:

Krchal72

Figure 2

After use IDA to analyze target, we will get all information related to the entire process of calculation and checking related to the Input Name that we entered.

signed int __stdcall sub_401740(int a1)
{
signed int k; // edi@1
char *v2; // ecx@2
signed int i; // esi@4
signed int j; // esi@8
__int16 v6; // bx@10
unsigned __int8 szName[0]; // al@15
unsigned __int8 iTemp1; // ST2C_1@15
unsigned __int8 szName[1]; // al@15
unsigned __int8 iTemp9; // bl@15
wchar_t *wcharBuf1; // eax@15
__int16 iBuf1; // di@15
__int16 szSerial[0]; // ax@15
wchar_t *wcharBuf2; // eax@16
__int16 szSerial[1]; // di@16
__int16 iBuf2; // ax@16
wchar_t *wcharBuf3; // eax@17
__int16 szSerial[2]; // di@17
__int16 iBuf3; // ax@17
wchar_t *wcharBuf4; // eax@18
__int16 szSerial[3]; // di@18
__int16 iBuf4; // ax@18
wchar_t *wcharBuf5; // eax@19
__int16 szSerial[4]; // di@19
__int16 iBuf5; // ax@19
unsigned __int8 szName[2]; // al@20
unsigned __int8 iTemp11; // ST2C_1@20
unsigned __int8 szName[3]; // al@20
unsigned __int8 iTemp19; // bl@20
wchar_t *wcharBuf6; // eax@20
__int16 szSerial[6]; // di@20
__int16 iBuf6; // ax@20
wchar_t *wcharBuf7; // eax@21
__int16 szSerial[7]; // di@21
__int16 iBuf7; // ax@21
wchar_t *wcharBuf8; // eax@22
__int16 szSerial[8]; // di@22
__int16 iBuf8; // ax@22
wchar_t *wcharBuf9; // eax@23
__int16 szSerial[9]; // di@23
__int16 iBuf9; // ax@23
wchar_t *wcharBuf10; // eax@24
__int16 szSerial[10]; // si@24
__int16 iBuf10; // ax@24
unsigned __int8 iTemp6; // [sp+10h] [bp-28h]@15
unsigned __int8 iTemp16; // [sp+10h] [bp-28h]@20
unsigned __int8 iTemp8; // [sp+11h] [bp-27h]@15
unsigned __int8 iTemp18; // [sp+11h] [bp-27h]@20
unsigned __int8 iTemp10; // [sp+13h] [bp-25h]@15
unsigned __int8 iTemp20; // [sp+13h] [bp-25h]@20
unsigned __int8 iTemp7; // [sp+14h] [bp-24h]@15
unsigned __int8 iTemp17; // [sp+14h] [bp-24h]@20
unsigned __int8 iTemp3; // [sp+19h] [bp-1Fh]@15
unsigned __int8 iTemp13; // [sp+19h] [bp-1Fh]@20
unsigned __int8 iTemp4; // [sp+1Ah] [bp-1Eh]@15
unsigned __int8 iTemp14; // [sp+1Ah] [bp-1Eh]@20
unsigned __int8 iTemp5; // [sp+1Bh] [bp-1Dh]@15
unsigned __int8 iTemp15; // [sp+1Bh] [bp-1Dh]@20
unsigned __int8 iTemp2; // [sp+1Ch] [bp-1Ch]@15
unsigned __int8 iTemp12; // [sp+1Ch] [bp-1Ch]@20
int szName; // [sp+20h] [bp-18h]@1
int szSerial; // [sp+24h] [bp-14h]@1
char buf; // [sp+28h] [bp-10h]@1
int iTemp; // [sp+34h] [bp-4h]@1

ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&szName);
k = 0;
iTemp = 0;
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&szSerial);
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&buf);
LOBYTE(iTemp) = 2;
CWnd::GetWindowTextW(a1 + 0x130, &szName);
if ( *(_DWORD *)(szName - 0xC) == 4 )
{
    i = 0;
    while ( (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&szName, i) >= 'a'
        && (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&szName, i) <= 'z' ) { ++i; if ( i >= 4 )
    {
first_loop:
        j = 0;
        while ( 1 )
        {
        if ( k != j )
        {
            v6 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szName, j);
            if ( (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&szName, k) == v6 )
            goto EndCheck;
        }
        ++j;
        if ( j >= 4 )
        {
            ++k;
            if ( k < 4 )
            goto first_loop;
            CWnd::GetWindowTextW(a1 + 0x1A4, &szSerial);
            if ( *(_DWORD *)(szSerial - 0xC) != 0xB
            || (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&szSerial, 5) != '-' )
            goto EndCheck;
            szName[0] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szName, 0);
            iTemp1 = (szName[0] & 1) + 5;
            iTemp2 = ((szName[0] >> 4) & 1) + 5;
            iTemp3 = ((szName[0] >> 1) & 1) + 5;
            iTemp4 = ((szName[0] >> 2) & 1) + 5;
            iTemp5 = ((szName[0] >> 3) & 1) + 5;
            szName[1] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szName, 1);
            iTemp6 = (szName[1] & 1) + 1;
            iTemp7 = ((szName[1] >> 4) & 1) + 1;
            iTemp8 = ((szName[1] >> 1) & 1) + 1;
            iTemp9 = ((szName[1] >> 2) & 1) + 1;
            iTemp10 = ((szName[1] >> 3) & 1) + 1;
            wcharBuf1 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&buf);
            itow_s(iTemp1 + iTemp9, wcharBuf1, 0xAu, 0xA);
            iBuf1 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&buf, 0);
            szSerial[0] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szSerial, 0);
            v2 = &buf;
            if ( szSerial[0] == iBuf1 )
            {
            ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&buf, 0xFFFFFFFF);
            wcharBuf2 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&buf);
            itow_s(iTemp5 + iTemp10, wcharBuf2, 0xAu, 0xA);
            szSerial[1] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szSerial, 1);
            iBuf2 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&buf, 0);
            v2 = &buf;
            if ( szSerial[1] == iBuf2 )
            {
                ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&buf, 0xFFFFFFFF);
                wcharBuf3 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&buf);
                itow_s(iTemp3 + iTemp7, wcharBuf3, 0xAu, 0xA);
                szSerial[2] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szSerial, 2);
                iBuf3 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&buf, 0);
                v2 = &buf;
                if ( szSerial[2] == iBuf3 )
                {
                ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&buf, 0xFFFFFFFF);
                wcharBuf4 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&buf);
                itow_s(iTemp4 + iTemp6, wcharBuf4, 0xAu, 0xA);
                szSerial[3] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szSerial, 3);
                iBuf4 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&buf, 0);
                v2 = &buf;
                if ( szSerial[3] == iBuf4 )
                {
                    ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&buf, 0xFFFFFFFF);
                    wcharBuf5 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&buf);
                    itow_s(iTemp2 + iTemp8, wcharBuf5, 0xAu, 0xA);
                    szSerial[4] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szSerial, 4);
                    iBuf5 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&buf, 0);
                    v2 = &buf;
                    if ( szSerial[4] == iBuf5 )
                    {
                    ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&buf, 0xFFFFFFFF);
                    szName[2] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szName, 2);
                    iTemp11 = (szName[2] & 1) + 5;
                    iTemp12 = ((szName[2] >> 4) & 1) + 5;
                    iTemp13 = ((szName[2] >> 1) & 1) + 5;
                    iTemp14 = ((szName[2] >> 2) & 1) + 5;
                    iTemp15 = ((szName[2] >> 3) & 1) + 5;
                    szName[3] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szName, 3);
                    iTemp16 = (szName[3] & 1) + 1;
                    iTemp17 = ((szName[3] >> 4) & 1) + 1;
                    iTemp18 = ((szName[3] >> 1) & 1) + 1;
                    iTemp19 = ((szName[3] >> 2) & 1) + 1;
                    iTemp20 = ((szName[3] >> 3) & 1) + 1;
                    wcharBuf6 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&buf);
                    itow_s(iTemp11 + iTemp19, wcharBuf6, 0xAu, 0xA);
                    szSerial[6] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szSerial, 6);
                    iBuf6 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&buf, 0);
                    v2 = &buf;
                    if ( szSerial[6] == iBuf6 )
                    {
                        ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&buf, 0xFFFFFFFF);
                        wcharBuf7 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&buf);
                        itow_s(iTemp15 + iTemp20, wcharBuf7, 0xAu, 0xA);
                        szSerial[7] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szSerial, 7);
                        iBuf7 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&buf, 0);
                        v2 = &buf;
                        if ( szSerial[7] == iBuf7 )
                        {
                        ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&buf, 0xFFFFFFFF);
                        wcharBuf8 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&buf);
                        itow_s(iTemp13 + iTemp17, wcharBuf8, 0xAu, 0xA);
                        szSerial[8] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szSerial, 8);
                        iBuf8 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&buf, 0);
                        v2 = &buf;
                        if ( szSerial[8] == iBuf8 )
                        {
                            ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&buf, 0xFFFFFFFF);
                            wcharBuf9 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&buf);
                            itow_s(iTemp14 + iTemp16, wcharBuf9, 0xAu, 0xA);
                            szSerial[9] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szSerial, 9);
                            iBuf9 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&buf, 0);
                            v2 = &buf;
                            if ( szSerial[9] == iBuf9 )
                            {
                            ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&buf, 0xFFFFFFFF);
                            wcharBuf10 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&buf);
                            itow_s(iTemp12 + iTemp18, wcharBuf10, 0xAu, 0xA);
                            szSerial[10] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szSerial, 0xA);
                            iBuf10 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&buf, 0);
                            v2 = &buf;
                            if ( szSerial[10] == iBuf10 )
                            {
                                ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&buf, 0xFFFFFFFF);
                                ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&buf);
                                ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&szSerial);
                                ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&szName);
                                return 1;
                            }
                            }
                        }
                        }
                    }
                    }
                }
                }
            }
            }
            goto end_check;
        }
        }
    }
    }
}
EndCheck:
v2 = &buf;
end_check:
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(v2);
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&szSerial);
ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&szName);
return 0;
}
szName[0] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szName, 0);
iTemp1 = (szName[0] & 1) + 5;
iTemp2 = ((szName[0] >> 4) & 1) + 5;
iTemp3 = ((szName[0] >> 1) & 1) + 5;
iTemp4 = ((szName[0] >> 2) & 1) + 5;
iTemp5 = ((szName[0] >> 3) & 1) + 5;
szName[1] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szName, 1);
iTemp6 = (szName[1] & 1) + 1;
iTemp7 = ((szName[1] >> 4) & 1) + 1;
iTemp8 = ((szName[1] >> 1) & 1) + 1;
iTemp9 = ((szName[1] >> 2) & 1) + 1;
iTemp10 = ((szName[1] >> 3) & 1) + 1;

szSerial[0] = 7 = iTemp1 + iTemp9
szSerial[1] = 6 = iTemp5 + iTemp10
szSerial[2] = 8 = iTemp3 + iTemp7
szSerial[3] = 7 = iTemp4 + iTemp6
szSerial[4] = 6 = iTemp2 + iTemp8

szName[2] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szName, 2);
iTemp11 = (szName[2] & 1) + 5;
iTemp12 = ((szName[2] >> 4) & 1) + 5;
iTemp13 = ((szName[2] >> 1) & 1) + 5;
iTemp14 = ((szName[2] >> 2) & 1) + 5;
iTemp15 = ((szName[2] >> 3) & 1) + 5;
szName[3] = ATL::CSimpleStringT<wchar_t,1>::GetAt(&szName, 3);
iTemp16 = (szName[3] & 1) + 1;
iTemp17 = ((szName[3] >> 4) & 1) + 1;
iTemp18 = ((szName[3] >> 1) & 1) + 1;
iTemp19 = ((szName[3] >> 2) & 1) + 1;
iTemp20 = ((szName[3] >> 3) & 1) + 1;

szSerial[6] = 7 = iTemp11 + iTemp19
szSerial[7] = 7 = iTemp15 + iTemp20
szSerial[8] = 7 = iTemp13 + iTemp17
szSerial[9] = 7 = iTemp14 + iTemp16
szSerial[10] = 6 = iTemp12 + iTemp18

Keygen source:

</pre>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int szName0, szName1;
    int iTemp1, iTemp2, iTemp3, iTemp4, iTemp5, iTemp6, iTemp7, iTemp8, iTemp9, iTemp10;
    int i=0, j=0;
    int szSerial[10] = {7,6,8,7,6,7,7,7,7,6};

    for (i=0; i<2; i++)
    {
        for (szName0 = 0x61; szName0 <= 0x7a; szName0++)
        {
            for (szName1 = 0x61; szName1 <= 0x7a; szName1++)
            {
                iTemp1 = (szName0 & 1) + 5;
                iTemp2 = ((szName0 >> 4) & 1) + 5;
                iTemp3 = ((szName0 >> 1) & 1) + 5;
                iTemp4 = ((szName0 >> 2) & 1) + 5;
                iTemp5 = ((szName0 >> 3) & 1) + 5;

                iTemp6 = (szName1 & 1) + 1;
                iTemp7 = ((szName1 >> 4) & 1) + 1;
                iTemp8 = ((szName1 >> 1) & 1) + 1;
                iTemp9 = ((szName1 >> 2) & 1) + 1;
                iTemp10 = ((szName1 >> 3) & 1) + 1;

                if ((iTemp1 + iTemp9) == szSerial[j])
                {
                    if ((iTemp5 + iTemp10) == szSerial[j+1])
                    {
                        if ((iTemp3 + iTemp7) == szSerial[j+2])
                        {
                            if ((iTemp4 + iTemp6) == szSerial[j+3])
                            {
                                if ((iTemp2 + iTemp8) == szSerial[j+4])
                                {
                                    printf("%c  %c\n", szName0, szName1);
                                }
                            }
                        }
                    }
                }

            }
        }
        printf("----------------------------\n");
        j = 5;
    }

    return 0;
}

Result after execute keygen:

Krchal73

Figure 3

Krchal74

Figure 4

End.


Run program, draw something and press check button. We’ll get the “Wrong” message box:

Krchal61

Figure 1

Load program to OllyDBG, search for all referenced text strings to find Wrong message:

Krchal62

Figure 2

Scroll up we can see a big loop that compare values at bl & cl, if not equal it will jump to the code displays wrong message:

Krchal63

Figure 3

Place bp at 004013A3 > > /8A11   mov   dl, byte ptr [ecx], press F9 to run, draw something and press check button, we will stop at bp. Look for the value store at [ecx] & [eax+ecx]:

Krchal64

Figure 4

Krchal65

Figure 5

Notice the 0x0047E060 address, this address belongs to rersource section (.rsrc):

Mem0ry map, item 22
 Address=0047E000
 Size=00016000 (90112.)
 Owner=ImagePrc 00400000
 Section=.rsrc
 Contains=resources
 Type=Imag 01001002
 Access=R
 Initial access=RWE

Convert VA 0x0047E060 to Offset, we have 0x9060. Let’s use hex editor to open program, go to 0x9060:

Krchal67

Figure 6

Find and select all offsets has 0xFF value, we have the block size is:

Krchal68

Figure 7

This value corressponding with the number of iterations that we see in the loop check. So we know that the memory area pointed by ecx register must contains all the same value. How can we have theses value? Scroll up to the top of function, we see the code:

0040116A   .  8D4424 48    lea     eax, dword ptr [esp+0x48]
0040116E   .  50            push    eax                              ; /pPaintstruct
0040116F   .  56            push    esi                              ; |hWnd
00401170   .  FF15 E0504000 call    dword ptr [<BeginPaint>]         ; \BeginPaint

The BeginPaint function prepares the specified window for painting and fills a PAINTSTRUCT structure with information about the painting. With this information, we guess that we have to draw something and then it can be used to compare with fixed data at offset 9060. Look at the code bellow BeginPaint:

0040117C   .  68 2000CC00           push    0xCC0020            ; /ROP = SRCCOPY
00401181   .  6A 00                 push    0x0                 ; |YSrc = 0x0
00401183   .  6A 00                 push    0x0                 ; |XSrc = 0x0
00401185   .  51                    push    ecx                 ; |hSrcDC => 0B0100AF
00401186   .  68 96000000           push    0x96                ; |Height = 96 (150.)
0040118B   .  68 C8000000           push    0xC8                ; |Width = C8 (200.)
00401190   .  6A 00                 push    0x0                 ; |YDest = 0x0
00401192   .  6A 00                 push    0x0                 ; |XDest = 0x0
00401194   .  50                    push    eax                 ; |hDestDC
00401195   .  FF15 30504000         call    dword ptr [<BitBlt>]; \BitBlt

The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into a destination device context. Scroll down a little bit, we see this code:

00401200   .  68 96000000           push    0x96                             ; /Height = 96 (150.)
00401205   .  68 C8000000           push    0xC8                             ; |Width = C8 (200.)
0040120A   .  56                    push    esi                              ; |hDC
0040120B   .  FF15 0C504000         call    dword ptr [<CreateCompatibleBitm>; \CreateCompatibleBitmap

The CreateCompatibleBitmap function creates a bitmap compatible with the device that is associated with the specified device context. Notice the Height and Width value, these value is the same with values at BitBlt call. Collect all information, we now know that we need to create a bitmap image with Height = 96 (150.) and Width = C8 (200.), and this image must contains 0x15F90 bytes from offset 0x9060. Let’s use mspaint to create a bitmap image with size is 200×150, open it in hex editor, then copy all data from offset 0x9060 and paste to offset of bitmap image that contains 0xFF values. Save image and open it, we get the flag:

Krchal69

Figure 8

End.


Rule: This MP3 Player is limited to 1 minutes. You have to play more than one minute. There are exist several 1-minute-check-routine. After bypassing every check routine, you will see the perfect flag.

Program is coded and compiled by MS Visual Basic 5.0-6.0. Execute file and play any mp3 file, we receive a message box when progress bar reach 1-minute:

Krchal51

Figure 1

Okay, load file to OllyDBG and search for all referenced text strings to find the string in the message box above, but can’t find any related information. So we have to set a BP to the MSVBVM60.rtcMsgBox API to find the code that displays the message box above. After place a breakpoint, press F9 to run the program and play mp3 file, we will reach here after play over 1 minute:

Krchal52

Figure 2

Go to 004045DE address, scroll up we’ll find the jump that by pass the call to rtcMsgBox:

Krchal53

Figure 3

Let’s patch this jump to unconditional jump like this:

Krchal54

Figure 4

Re-run program, play file again and see what’s happen:

Krchal55

Figure 5

Huh… Run time error! May be this program has another check, so we need to find the code section that make program crash. Restart OllyDBG, press F9 to run, then open and play mp3 file. Wait until the it plays file about 57 – 58 seconds, back to OllyDBG immediately and set BP at 0040456B . /0F8C 8D000000   jl Music_Pl.004045FE. Program will stop at BP like the picture bellow:

Krchal56

Figure 6

Patch to JMP to skip the call displays a message limited playing music file within 1 minute, continue trace over with F8, we’ll find the code that make program crash:

Krchal57

Figure 7

Scroll up and patch the jump to by pass this call above:

Krchal58

Figure 8

After patch two check location, press F9 to run program … we will see the flag at the caption:

Krchal59

Figure 9

Flag is : LIstenCare

End.


Rule: Find the Name when the Serial is 5B134977135E7D13

With the above Serial, we can guess the Name will have 8 characters. Combine analysis target by both IDA and OllyDBG, we have the pseudo code is:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  signed int j; // ebp@1
  signed int i; // esi@1
  int result; // eax@6
  int v6; // [sp+0h] [bp-13Ch]@0
  int v7; // [sp+0h] [bp-13Ch]@1
  char defVal[3]; // [sp+Ch] [bp-130h]@1
  char szBuff; // [sp+10h] [bp-12Ch]@1
  char v10; // [sp+11h] [bp-12Bh]@1
  __int16 v11; // [sp+71h] [bp-CBh]@1
  char v12; // [sp+73h] [bp-C9h]@1
  char szCalSerial; // [sp+74h] [bp-C8h]@1
  char v14; // [sp+75h] [bp-C7h]@1
  __int16 v15; // [sp+139h] [bp-3h]@1
  char v16; // [sp+13Bh] [bp-1h]@1

  szBuff = 0;
  szCalSerial = 0;
  memset(&v10, 0, 0x60u);
  v11 = 0;
  v12 = 0;
  memset(&v14, 0, 0xC4u);
  v15 = 0;
  v16 = 0;
  defVal[0] = 0x10;
  defVal[1] = 0x20;
  defVal[2] = 0x30;
  sub_4011B9((int)"Input Name: ", v6);
  scanf("%s", &szBuff);
  j = 0;
  for ( i = 0; j < (signed int)strlen(&szBuff); ++i ) { if ( i >= 3 )
      i = 0;
    sprintf(&szCalSerial, "%s%02X", &szCalSerial, *(&szBuff + j++) ^ defVal[i]);
  }
  memset(&szBuff, 0, 0x64u);
  sub_4011B9((int)"Input Serial: ", v7);
  scanf("%s", &szBuff);
  if ( !strcmp(&szBuff, &szCalSerial) )
  {
    sub_4011B9((int)"Correct!\n", *(int *)defVal);
    result = 0;
  }
  else
  {
    sub_4011B9((int)"Wrong\n", *(int *)defVal);
    result = 0;
  }
  return result;
}

Very clearly, this code gets the Input Name to szBuff. Through the loop to convert the Input Name by using XOR operator with defVal array and finally store value at szCalSerial. After that it compares Input Serial with szCalSerial, so szCalSerial must equal “5B134977135E7D13”. Perform reverse the XOR calculations we’ll have the correct Input Name:

Input_Name[0] ^ 0x10 = 5B -> 4B K
Input_Name[1] ^ 0x20 = 13 -> 33 3
Input_Name[2] ^ 0x30 = 49 -> 79 y
Input_Name[3] ^ 0x10 = 77 -> 67 g
Input_Name[4] ^ 0x20 = 13 -> 33 3
Input_Name[5] ^ 0x30 = 5E -> 6E n
Input_Name[6] ^ 0x10 = 7D -> 6D m
Input_Name[7] ^ 0x20 = 13 -> 33 3
  • Right Input Name : K3yg3nm3

End.


First, run file and input fake key, press check button. The program is crashed:

Krchal31

Figure 1

Use OllyDBG to load file and search for all referenced text strings:

Krchal32

Figure 2

Double-click on the “ASCII “Correct!”” will back to the disassembly window.

Krchal33

Figure 3

We see to JMP instructions above that will bypass the “Correct!” string. Scroll up a little bit and set BP at: 0040105A . FF15 9C504000     call   dword ptr [<GetDlgItemInt>] ; \GetDlgItemInt

Press F9 to run, input fake key to text box, then click Check button, we will stop at bp

Krchal34

Figure 4

EAX register contains the fake key and then fake key is stored at ds:[004084D0]=00000000. We need to trace into the 00401065   . E8 05360000       call   Replace.0040466F ; to see what happen with the fake key?

Krchal35

Figure 5

Review the code at 0040466F, we have some calls that can used to check or calculate something and at the end of this function, we see the jmp instruction that jump back to the 00401071 address. At 00401071 is the jump instruction that bypass the Correct message!! Continue to trace with F7:

0040467A         .  C705 16604000>mov     dword ptr [406016], 619060EB            ;  <-- mov opcode 0x619060EB to [406016]
Krchal36

Figure 6

Continue with this code:

00404684         .  E8 00000000   call    Replace.00404689
00404689        /$  FF05 D0844000 inc     dword ptr [<InputKey>]  ;  <- InputKey ++
0040468F        \.  C3            retn

Pseudo code: InputKey = InputKey + 1 + 1. Then return to this instruction:

00404674          8105 D0844000 C7051660   add     dword ptr [<InputKey>], 601605C7 ; <- InputKey +  0x601605C7

After trace over this instruction, we have: InputKey = InputKey + 0x601605C7
Next, we go to these codes same as we see above:

0040467E          40                       inc     eax
0040467F          00EB                     add     bl, ch
00404681          60                       pushad
00404682          90                       nop
00404683          61                       popad
00404684          E8 00000000              call    Replace.00404689
00404689          FF05 D0844000            inc     dword ptr [<InputKey>]  ; <- InputKey ++
0040468F          C3                       retn

This code again increases InputKey: InputKey = InputKey + 1 + 1. Summerize, we have: InputKey = InputKey + 1 + 1 + 0x601605C7 + 1 + 1 (Example: If the InputKey is 123456789 (0x75B CD15), after calculate we have result is 0x6771 D2E0). After have the result of InputKey, we will return to:

Krchal37

Figure 7

Trace over the JMP, we land at this code:

Krchal38

Figure 8

Krchal39

Figure 9

Notice the JMP that jump back to 00401071. First, this code loads InputKey that calculated above to EAX, then replace the content of 40466F to asm instruction with opcode is 0xC39000C6:

Krchal310

Figure 10

Bellow 0040469F C705 6F464000 C60090C3 mov dword ptr [40466F], C39000C6 ; , we see two call instruction to 40466F. Cause EAX contains InputKey value, so at 40466F will mov the hex value 0x90 to the content of EAX (in other words, it is the content of InputKey). 0x90 equivalent to NOP instruction. Thus, we can see two NOP instructions is used to assign to the content of EAX. Finally, we jump back to the 0x401071 (004046C4 ^\E9 A8C9FFFF   jmp     Replace.00401071), at this address we see the jmp that bypass the Correct message:

Krchal311

Figure 11

At 401071 address, we need to NOP the jmp instruction so that can not jump out of the code that contains the correct string. With this idea and along with the entire process of code analysis above, we need to enter the InputKey, then after calculation code we’ll have value is 401071. So the right InputKey is:

InputKey + 1 + 1 + 0x601605C7 + 1 + 1 = 0x401071

  • InputKey = 0x00401071 - 1 - 1 - 0x601605C7 - 1 – 1 = FFFFFFFFA02A0AA6
  • FFFFFFFFA02A0AA6 + 100000000 = A02A 0AA6 (2687109798 in decimal format)
Krchal312

Figure 12

End.

Load Easy_UnpackMe to OllyDBG, scroll down to find JMP instruction:

Krchal21

Figure 1

Set BP at 0040A1FB - E9 506FFFFF     jmp     Easy_Unp.00401150, press F9 to run. Stop at BP, press F8 to trace over, we get the OEP is 0x00401150:

Krchal22

Figure 2

Anotherway to find OEP is to set BP at GetVersion API:

Krchal23

Figure 3

End.


Load target to OllyDBG and search all referenced text strings:

Krchal1

Figure 1

Double click on the “Congratulation  !!”, go here:

Krchal2

Figure 2

Scroll up a little bit and set a BP at GetDlgItemTextA:

Krchal3

Figure 3

Press F9 to run, input any key that you want:

004010B0    |.  807C24 05 61  cmp     byte ptr [esp+5], 61        ;  <- InputKey[1] = 'a'?
004010B5    |.  75 7E         jnz     short Easy_Cra.00401135     ;  <- If not, show incorrect!
004010B7    |.  6A 02         push    2
004010B9    |.  8D4C24 0A     lea     ecx, dword ptr [esp+A]
004010BD    |.  68 78604000   push    Easy_Cra.00406078           ;  ASCII "5y"
004010C2    |.  51            push    ecx
004010C3    |.  E8 88000000   call    Easy_Cra.00401150           ;  <- InputKey[2,3] = '5y'?
004010C8    |.  83C4 0C       add     esp, 0C
004010CB    |.  85C0          test    eax, eax
004010CD    |.  75 66         jnz     short Easy_Cra.00401135     ;  <- If not, show incorrect!
004010CF    |.  53            push    ebx
004010D0    |.  56            push    esi
004010D1    |.  BE 6C604000   mov     esi, Easy_Cra.0040606C      ;  ASCII "R3versing"
004010D6    |.  8D4424 10     lea     eax, dword ptr [esp+10]
004010DA    |>  8A10          /mov     dl, byte ptr [eax]
004010DC    |.  8A1E          |mov     bl, byte ptr [esi]
004010DE    |.  8ACA          |mov     cl, dl
004010E0    |.  3AD3          |cmp     dl, bl
004010E2    |.  75 1E         |jnz     short Easy_Cra.00401102
004010E4    |.  84C9          |test    cl, cl
004010E6    |.  74 16         |je      short Easy_Cra.004010FE
004010E8    |.  8A50 01       |mov     dl, byte ptr [eax+1]       ;  <-- This loop compare InputKey[4...] =  'R3versing'
004010EB    |.  8A5E 01       |mov     bl, byte ptr [esi+1]
004010EE    |.  8ACA          |mov     cl, dl
004010F0    |.  3AD3          |cmp     dl, bl
004010F2    |.  75 0E         |jnz     short Easy_Cra.00401102
004010F4    |.  83C0 02       |add     eax, 2
004010F7    |.  83C6 02       |add     esi, 2
004010FA    |.  84C9          |test    cl, cl
004010FC    |.^ 75 DC         \jnz     short Easy_Cra.004010DA
004010FE    |>  33C0          xor     eax, eax
00401100    |.  EB 05         jmp     short Easy_Cra.00401107
00401102    |>  1BC0          sbb     eax, eax
00401104    |.  83D8 FF       sbb     eax, -1
00401107    |>  5E            pop     esi
00401108    |.  5B            pop     ebx
00401109    |.  85C0          test    eax, eax
0040110B    |.  75 28         jnz     short Easy_Cra.00401135
0040110D    |.  807C24 04 45  cmp     byte ptr [esp+4], 45        ;  <-- InputKey[0] = 'E'?
00401112    |.  75 21         jnz     short Easy_Cra.00401135     ;  <- If not, show incorrect!

After tracing through this code, we can get the correct Input Key is: Ea5yR3versing

End.


Note lại mấy cái Plugin của các bạn Tung Quở. Thông tin mô tả được dịch bởi Google Translate🙂

OllyDisasm201: I believe a lot of friends using times OD1.1 and often encounter some of the instructions not recognize; or be able to identify but not a single step, resulting in unable to analysis, this plug-in is solve this problem.

OllyRecord: This plug-in function slightly more points, there are three main functions, the conditions hard off the record, dynamically symbol loading, Advanced Edition CTRL + G, after two I was not introduced, everyone will be under exploration, said the main condition record breaking hard.

Hard-off condition record:
Use Scenario 1: In analyzing the packet times, a lot of time trying to send and receive packets can be recorded, but do not want to write the DLL HOOK, this times you can use this
The following example, when the instruction flow through the 0101249E address, if ebx> = 0x65 && ebx <= 0x67, is recorded as a pointer to eax, ebx length packets (where eax, ebx can be replaced by an expression such as “% {BYTE PTR [EBX + 3]]} b “, [EBX + 100])

 1

Use Scenario 2: Analysis of function calls in times, you can also use this to record which CALL the function is invoked before, and the parameter values are passed in the number

2

There are also many other uses, as long as the plug-in will be used, the other can take the time to research their own.

Download here: https://mega.nz/#!zt1gAQaA!P19K8xnzURYfzjy5NmBf3hUgsq02VFK4GbPMXJLxFZs

Regards,


Link: https://forum.tuts4you.com/topic/37666-crackme-find-the-flag-by-extremecoders/

Cái crackme này lúc đầu download về, cho vào IDA analyse, nhìn đống messy code xong thấy ngơ luôn, như kiểu thanh niên ngáo đá muốn phá đảo thế giới ảo ….emo_popo_choler. Sau đọc được bài write-up của kao (http://lifeinhex.com/solving-find-the-flag-crackme-by-extreme-coders/), thấy dị dị nên note lại. sexy_girl.

Load crackme vào IDA, quan sát code tại _main thấy như sau:

2015-11-05_9-39-22Đặt BP tại lệnh popa:

2015-11-05_9-53-19Tiến hành debug, dừng lại tại bp, quan sát thấy vùng code đã được giải mã như sau:

2015-11-05_9-57-35Cuộn chuột xuống dưới để xem code đã được giải mã hết chưa thì lại bắt gặp vòng lặp xor nữa beated và vùng code bị encrypted ở dưới còn rất nhiều:

2015-11-05_10-03-252015-11-05_10-04-38Việc đặt BP để decrypt code bằng tay sẽ mất nhiều thời gian và không hiệu quả. Cách hiệu quả nhất là dùng script để thực hiện việc giải mã một cách tự động. Script thực hiện quá trình giải mã như sau:

/* IDC Script: this script automate decrypt all encrypted code */
//declare local variables
auto ea;
auto addr;
auto size;
auto xorval;
auto x;
auto b;
 
ea = MinEA(); //set ea to the lowest address used in the program (ea = 401000h)
ea = FindBinary(ea, SEARCH_DOWN , "E8 00 00 00 00 5E 81 C6"); // search for the specified byte. If not found return BADADDR. Ex: First found at 40103Bh
while (ea != BADADDR)
{
   addr = ea + 5 + 0x16;      //get adrr of encrypted code (ex: addr = 40103Bh + 5 + 0x16 = 401056h)
   size = Dword(ea + 0xD);    //get size of encrypted code at ea (40103Bh), ex: size = 204h
   xorval = Byte(ea + 0x15);  //get xor key, ex: xorval = 86h

   Message(form("Encrypted code parameters: start=%x size=%x key=%x\n", addr, size, xorval));
   for (x=0; x<size; x++)
   {
      b = Byte(addr + x);
      PatchByte(addr + x, b^xorval);
   }
   ea = FindBinary(ea +1, SEARCH_DOWN, "E8 00 00 00 00 5E 81 C6"); //next found, ex: ea = 401277h
}

Toàn bộ đoạn script trên thực hiện việc tìm kiếm vùng code liên quan đến việc giải mã, sau đó trích xuất các thông tin liên quan tới vùng code bị encrypted, gồm địa chỉ (ea), kích thước (size), key mã hóa (xorval). Sau khi có đủ thông tin, thực hiện việc giải mã.

Để thực thi script, reanalyse lại crackme trong IDA, tại _main nhấn Shift-F2, nhập script và cho thực thi:

2015-11-05_10-24-53Sau khi toàn bộ code đã được giải mã xong, thực hiện tái tạo lại hàm _main do ban đầu đã bị sai: .text:00401056 _main endp ; sp-analysis failed.

2015-11-05_10-50-56Phân tích sơ bộ và đặt tên lại một số biến, ta có được thông tin sau:

2015-11-05_11-01-16Sau đó Flag nhập vào sẽ được sử dung để tính toán và so sánh, ví dụ như các đoạn code sau:

2015-11-05_11-04-562015-11-05_11-07-24Mã giả có được bằng Hexrays:

v12 = 0x88;
  do
  {
    --v12;
    *(_BYTE *)(v12 + 0x401333) ^= 0x26u;
  }
  while ( v12 );
  size_EncryptCode4 = 0x88;
  do
  {
    --size_EncryptCode4;
    *(_BYTE *)(size_EncryptCode4 + 0x4013F3) ^= 0x8Eu;
  }
  while ( size_EncryptCode4 );
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[23]
     + enteredString[26]
     + enteredString[14]
     + enteredString[24]
     + enteredString[17]
     + enteredString[12]
     + enteredString[10]
     + enteredString[15]
     + enteredString[4]
     + enteredString[2]
     + enteredString[6]
     + enteredString[1]
     + enteredString[29]
     + enteredString[11]
     + 2 * (enteredString[9] + enteredString[19]) == 1927 )
    ++iResult;
  v14 = 0x88;
  do
  {
    --v14;
    *(_BYTE *)(v14 + 0x4013F3) ^= 0x8Eu;
  }
  while ( v14 );
  size_EncryptCode5 = 0x17;
  do
  {
    --size_EncryptCode5;
    *(_BYTE *)(size_EncryptCode5 + 0x4014B3) ^= 0x29u;
  }
  while ( size_EncryptCode5 );

Tóm lại, đếm sơ sơ thì có khoảng gần 100 vùng code tính toán và kiểm tra kiểu như trênextreme_sexy_girl. Lẫn lộn trong đống code này là các đoạn code chịu trách nhiệm encryp/decrypt.

Toàn bộ code có được của hàm _main bằng HexRays:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  FILE *v3; // eax@1
  HMODULE handle_kernel32; // eax@1
  FARPROC addr_Sleep; // esi@1
  signed int iResult; // eax@1
  char enteredString[32]; // [sp+10h] [bp-A0h]@1
  char ProcName[6]; // [sp+30h] [bp-80h]@1
  char ModuleName[9]; // [sp+38h] [bp-78h]@1
  char def_string2[17]; // [sp+44h] [bp-6Ch]@1
  char def_string1[61]; // [sp+58h] [bp-58h]@1
  char v13; // [sp+95h] [bp-1Bh]@1
  char str_Result_Msg[19]; // [sp+98h] [bp-18h]@201

  *(_DWORD *)enteredString = 0;
  *(_DWORD *)&enteredString[4] = 0;
  *(_DWORD *)&enteredString[8] = 0;
  *(_DWORD *)&enteredString[12] = 0;
  *(_DWORD *)&enteredString[16] = 0;
  *(_DWORD *)&enteredString[20] = 0;
  *(_DWORD *)&enteredString[24] = 0;
  *(_DWORD *)&enteredString[28] = 0;
  def_string1[0] = '-';
  def_string1[1] = '-';
  def_string1[2] = '-';
  def_string1[3] = '-';
  def_string1[4] = '-';
  def_string1[5] = '-';
  def_string1[6] = '-';
  def_string1[7] = '-';
  def_string1[8] = '-';
  def_string1[9] = '-';
  def_string1[51] = '-';
  def_string1[52] = '-';
  def_string1[53] = '-';
  def_string1[54] = '-';
  def_string1[55] = '-';
  def_string1[56] = '-';
  def_string1[57] = '-';
  def_string1[58] = '-';
  def_string1[59] = '-';
  def_string1[60] = '-';
  def_string1[10] = 'F';
  def_string1[11] = 'i';
  def_string1[12] = 'n';
  def_string1[13] = 'd';
  def_string1[14] = ' ';
  def_string1[15] = 't';
  def_string1[16] = 'h';
  def_string1[17] = 'e';
  def_string1[18] = ' ';
  def_string1[19] = 'f';
  def_string1[20] = 'l';
  def_string1[21] = 'a';
  def_string1[22] = 'g';
  def_string1[23] = ':';
  def_string1[24] = ' ';
  def_string1[25] = 'B';
  def_string1[26] = 'y';
  def_string1[27] = ' ';
  def_string1[28] = 'E';
  def_string1[29] = 'x';
  def_string1[30] = 't';
  def_string1[31] = 'r';
  def_string1[32] = 'e';
  def_string1[33] = 'm';
  def_string1[34] = 'e';
  def_string1[35] = 'C';
  def_string1[36] = 'o';
  def_string1[37] = 'd';
  def_string1[38] = 'e';
  def_string1[39] = 'r';
  def_string1[40] = 's';
  def_string1[41] = ',';
  def_string1[42] = ' ';
  def_string1[43] = 'N';
  def_string1[44] = 'o';
  def_string1[45] = 'v';
  def_string1[46] = ' ';
  def_string1[47] = '2';
  def_string1[48] = '0';
  def_string1[49] = '1';
  def_string1[50] = '5';
  v13 = '\0';
  puts(def_string1);
  puts("\n\n");
  def_string2[0] = 'E';
  def_string2[1] = 'n';
  def_string2[2] = 't';
  def_string2[3] = 'e';
  def_string2[4] = 'r';
  def_string2[5] = ' ';
  def_string2[6] = 'y';
  def_string2[7] = 'o';
  def_string2[8] = 'u';
  def_string2[9] = 'r';
  def_string2[10] = ' ';
  def_string2[11] = 'f';
  def_string2[12] = 'l';
  def_string2[13] = 'a';
  def_string2[14] = 'g';
  def_string2[15] = ':';
  def_string2[16] = '\0';
  puts(def_string2);
  puts("\n");
  v3 = (FILE *)sub_404DF4();
  fgets(enteredString, 31, v3);
  ModuleName[0] = 'k';
  ModuleName[1] = 'e';
  ModuleName[2] = 'r';
  ModuleName[3] = 'n';
  ModuleName[4] = 'e';
  ModuleName[5] = 'l';
  ModuleName[6] = '3';
  ModuleName[7] = '2';
  ModuleName[8] = '\0';
  handle_kernel32 = GetModuleHandleA(ModuleName);
  ProcName[0] = 'S';
  ProcName[1] = 'l';
  ProcName[2] = 'e';
  ProcName[3] = 'e';
  ProcName[4] = 'p';
  ProcName[5] = '\0';
  addr_Sleep = GetProcAddress(handle_kernel32, ProcName);
  ((void (__stdcall *)(signed int))addr_Sleep)(750);
  iResult = 0;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[26]
     + enteredString[20]
     + enteredString[10]
     + enteredString[7]
     + 3 * enteredString[14]
     + 2
     * (enteredString[23]
      + enteredString[24]
      + enteredString[17]
      + enteredString[21]
      + enteredString[12]
      + enteredString[18]) == 2024 )
    iResult = 1;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[23]
     + enteredString[26]
     + enteredString[14]
     + enteredString[24]
     + enteredString[17]
     + enteredString[12]
     + enteredString[10]
     + enteredString[15]
     + enteredString[4]
     + enteredString[2]
     + enteredString[6]
     + enteredString[1]
     + enteredString[29]
     + enteredString[11]
     + 2 * (enteredString[9] + enteredString[19]) == 1927 )
    ++iResult;
  if ( enteredString[14] + enteredString[10] == 148 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[14]
     + enteredString[10]
     + enteredString[11]
     + enteredString[3]
     + enteredString[25]
     + 2 * (enteredString[22] + enteredString[27]) == 741 )
    ++iResult;
  if ( enteredString[24] + enteredString[29] == 229 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[26]
     + enteredString[20]
     + enteredString[21]
     + enteredString[12]
     + enteredString[7]
     + enteredString[9]
     + enteredString[15]
     + enteredString[4]
     + enteredString[1]
     + enteredString[29]
     + enteredString[11]
     + enteredString[3]
     + enteredString[27]
     + enteredString[25]
     + enteredString[5]
     + enteredString[8]
     + enteredString[16]
     + 2 * (enteredString[6] + enteredString[19]) == 2133 )
    ++iResult;
  if ( enteredString[14]
     + enteredString[17]
     + enteredString[7]
     + enteredString[15]
     + enteredString[11]
     + enteredString[8] == 619 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[26]
     + enteredString[21]
     + enteredString[12]
     + enteredString[7]
     + enteredString[11]
     + enteredString[16]
     + enteredString[28]
     + 2 * enteredString[23] == 996 )
    ++iResult;
  if ( enteredString[24]
     + enteredString[17]
     + enteredString[6]
     + enteredString[1]
     + enteredString[29]
     + 2 * enteredString[21] == 717 )
    ++iResult;
  if ( enteredString[24]
     + enteredString[21]
     + enteredString[12]
     + enteredString[18]
     + enteredString[6]
     + enteredString[29]
     + enteredString[11]
     + enteredString[8]
     + enteredString[16]
     + 3 * enteredString[26]
     + 2
     * (enteredString[0]
      + enteredString[17]
      + enteredString[2]
      + enteredString[19]
      + enteredString[5]
      + enteredString[28]
      + enteredString[13]) == 2308 )
    ++iResult;
  if ( enteredString[20]
     + enteredString[17]
     + enteredString[21]
     + enteredString[7]
     + enteredString[9]
     + enteredString[1]
     + enteredString[19]
     + enteredString[11]
     + enteredString[27]
     + enteredString[8]
     + enteredString[28]
     + 3 * (enteredString[14] + enteredString[3])
     + 2 * (enteredString[0] + enteredString[23] + enteredString[18] + enteredString[6]) == 2347 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[26]
     + enteredString[20]
     + enteredString[24]
     + enteredString[10]
     + enteredString[9]
     + enteredString[6]
     + enteredString[11]
     + enteredString[25]
     + 2 * (enteredString[23] + enteredString[28]) == 1041 )
    ++iResult;
  if ( enteredString[23] + enteredString[6] + enteredString[27] == 184 )
    ++iResult;
  if ( enteredString[23]
     + enteredString[18]
     + enteredString[9]
     + enteredString[19]
     + enteredString[11]
     + enteredString[25]
     + enteredString[5]
     + enteredString[16]
     + 2 * enteredString[1] == 1076 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[26]
     + enteredString[20]
     + enteredString[24]
     + enteredString[10]
     + enteredString[7]
     + enteredString[4]
     + enteredString[2]
     + enteredString[6]
     + enteredString[19]
     + enteredString[11] == 1040 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[23]
     + enteredString[14]
     + enteredString[18]
     + enteredString[10]
     + enteredString[4]
     + enteredString[6]
     + enteredString[1]
     + enteredString[19]
     + enteredString[11]
     + enteredString[8]
     + enteredString[16]
     + enteredString[28]
     + 5 * enteredString[21]
     + 3 * enteredString[13]
     + 2 * (enteredString[26] + enteredString[24]) == 2393 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[23]
     + enteredString[26]
     + enteredString[24]
     + enteredString[9]
     + enteredString[15]
     + enteredString[29]
     + enteredString[11]
     + enteredString[25] == 901 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[18]
     + enteredString[10]
     + enteredString[7]
     + enteredString[9]
     + enteredString[29]
     + enteredString[11]
     + enteredString[28]
     + 3 * enteredString[26] == 893 )
    ++iResult;
  if ( enteredString[18] + enteredString[11] + enteredString[3] == 308 )
    ++iResult;
  if ( enteredString[22]
     + enteredString[14]
     + enteredString[20]
     + enteredString[12]
     + enteredString[10]
     + enteredString[4]
     + enteredString[2]
     + enteredString[19]
     + enteredString[29]
     + enteredString[5]
     + enteredString[8]
     + enteredString[13]
     + 2 * enteredString[18] == 1350 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[26]
     + enteredString[14]
     + enteredString[20]
     + enteredString[17]
     + enteredString[7]
     + enteredString[9]
     + enteredString[1]
     + enteredString[19]
     + enteredString[5]
     + enteredString[8]
     + 2 * (enteredString[15] + enteredString[29] + enteredString[28]) == 0x62C )
    ++iResult;
  if ( enteredString[14]
     + enteredString[20]
     + enteredString[24]
     + enteredString[12]
     + enteredString[18]
     + enteredString[10]
     + enteredString[15]
     + enteredString[6]
     + enteredString[29]
     + enteredString[3]
     + enteredString[25]
     + 3 * enteredString[21]
     + 2 * (enteredString[0] + enteredString[7] + enteredString[4]) == 0x81B )
    ++iResult;
  if ( enteredString[23]
     + enteredString[26]
     + enteredString[24]
     + enteredString[17]
     + enteredString[21]
     + enteredString[18]
     + enteredString[10]
     + enteredString[6]
     + enteredString[11]
     + enteredString[5]
     + enteredString[8]
     + enteredString[13]
     + 3 * enteredString[22]
     + 2 * (enteredString[7] + enteredString[9] + enteredString[27]) == 0x6B9 )
    ++iResult;
  if ( enteredString[11] + enteredString[28] == 141 )
    ++iResult;
  if ( enteredString[26]
     + enteredString[24]
     + enteredString[17]
     + enteredString[12]
     + enteredString[7]
     + enteredString[4]
     + enteredString[29]
     + enteredString[5]
     + enteredString[16]
     + enteredString[13]
     + 2 * (enteredString[22] + enteredString[15] + enteredString[25]) == 0x60E )
    ++iResult;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[20]
     + enteredString[17]
     + enteredString[18]
     + enteredString[15]
     + enteredString[2]
     + enteredString[1]
     + enteredString[19]
     + enteredString[27]
     + enteredString[5]
     + enteredString[16]
     + enteredString[13]
     + 2
     * (enteredString[14]
      + enteredString[24]
      + enteredString[10]
      + enteredString[7]
      + enteredString[6]
      + enteredString[11]
      + enteredString[25]) == 0x9B4 )
    ++iResult;
  if ( enteredString[22]
     + enteredString[17]
     + enteredString[10]
     + enteredString[5]
     + enteredString[16]
     + 2 * (enteredString[20] + enteredString[24]) == 0x324 )
    ++iResult;
  if ( enteredString[7]
     + enteredString[4]
     + enteredString[2]
     + enteredString[27]
     + enteredString[25]
     + enteredString[5]
     + enteredString[8]
     + enteredString[16]
     + enteredString[13]
     + 3 * (enteredString[22] + enteredString[24] + enteredString[9])
     + 2 * (enteredString[0] + enteredString[1] + enteredString[28] + 2 * enteredString[10]) == 0x941 )
    ++iResult;
  if ( enteredString[23]
     + enteredString[17]
     + enteredString[12]
     + enteredString[27]
     + enteredString[16]
     + 2 * enteredString[9] == 0x2C0 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[26]
     + enteredString[24]
     + enteredString[10]
     + enteredString[7]
     + enteredString[4]
     + enteredString[6]
     + enteredString[1]
     + enteredString[29]
     + enteredString[11]
     + enteredString[3]
     + enteredString[27]
     + enteredString[5]
     + enteredString[8]
     + enteredString[13]
     + 3 * enteredString[20]
     + 2 * (enteredString[22] + enteredString[14] + enteredString[15]) == 0x83E )
    ++iResult;
  if ( enteredString[26]
     + enteredString[14]
     + enteredString[21]
     + enteredString[18]
     + enteredString[9]
     + enteredString[15]
     + enteredString[2]
     + enteredString[29]
     + enteredString[3]
     + enteredString[5] == 968 )
    ++iResult;
  if ( enteredString[24]
     + enteredString[12]
     + enteredString[4]
     + enteredString[1]
     + enteredString[19]
     + enteredString[3]
     + enteredString[16]
     + 2 * (enteredString[26] + enteredString[21] + enteredString[6] + enteredString[5]) == 1356 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[21]
     + enteredString[9]
     + enteredString[15]
     + enteredString[29]
     + enteredString[3]
     + enteredString[5]
     + 3 * enteredString[23]
     + 2 * (enteredString[12] + enteredString[7] + enteredString[19] + enteredString[27]) == 0x74D )
    ++iResult;
  if ( enteredString[26]
     + enteredString[14]
     + enteredString[18]
     + enteredString[7]
     + enteredString[9]
     + enteredString[2]
     + enteredString[1]
     + enteredString[3]
     + enteredString[5]
     + enteredString[8]
     + enteredString[28]
     + 2
     * (enteredString[0]
      + enteredString[20]
      + enteredString[17]
      + enteredString[21]
      + enteredString[15]
      + enteredString[6]
      + enteredString[19]
      + enteredString[25]
      + enteredString[13]) == 2769 )
    ++iResult;
  if ( enteredString[22]
     + enteredString[23]
     + enteredString[10]
     + enteredString[15]
     + enteredString[19]
     + enteredString[11]
     + enteredString[8]
     + enteredString[28]
     + 2
     * (enteredString[0]
      + enteredString[24]
      + enteredString[1]
      + enteredString[3]
      + enteredString[27]
      + 2 * (enteredString[26] + enteredString[7])) == 2147 )
    ++iResult;
  if ( enteredString[23]
     + enteredString[14]
     + enteredString[20]
     + enteredString[24]
     + enteredString[17]
     + enteredString[19]
     + enteredString[11]
     + enteredString[3]
     + enteredString[25]
     + enteredString[13]
     + 2
     * (enteredString[0]
      + enteredString[21]
      + enteredString[9]
      + enteredString[2]
      + enteredString[6]
      + enteredString[1]
      + enteredString[16]) == 2450 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[26]
     + enteredString[24]
     + enteredString[17]
     + enteredString[21]
     + enteredString[18]
     + enteredString[10]
     + enteredString[9]
     + enteredString[19]
     + enteredString[27]
     + enteredString[25]
     + 3 * (enteredString[11] + enteredString[13])
     + 2 * (enteredString[12] + enteredString[28] + 2 * (enteredString[1] + enteredString[3])) == 2755 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[23]
     + enteredString[26]
     + enteredString[20]
     + enteredString[21]
     + enteredString[12]
     + enteredString[7]
     + enteredString[9]
     + enteredString[2]
     + enteredString[1]
     + enteredString[11]
     + enteredString[5]
     + enteredString[16]
     + 3 * (enteredString[6] + enteredString[25])
     + 2 * (enteredString[24] + enteredString[18] + enteredString[10] + enteredString[15] + enteredString[28]) == 2561 )
    ++iResult;
  if ( enteredString[21] + enteredString[4] + enteredString[19] + enteredString[5] + 2 * enteredString[14] == 642 )
    ++iResult;
  if ( enteredString[20]
     + enteredString[24]
     + enteredString[17]
     + enteredString[4]
     + enteredString[27]
     + enteredString[25]
     + enteredString[8]
     + enteredString[16]
     + 3 * enteredString[19]
     + 2 * (enteredString[26] + enteredString[14] + enteredString[7] + enteredString[13] + 2 * enteredString[29]) == 0x920 )
    ++iResult;
  if ( enteredString[20]
     + enteredString[24]
     + enteredString[12]
     + enteredString[18]
     + enteredString[10]
     + 3 * enteredString[3]
     + 2
     * (enteredString[17]
      + enteredString[21]
      + enteredString[9]
      + enteredString[15]
      + enteredString[2]
      + enteredString[1]
      + enteredString[19]
      + enteredString[29]
      + enteredString[11]
      + enteredString[8]) == 2925 )
    ++iResult;
  if ( enteredString[23]
     + enteredString[20]
     + enteredString[24]
     + enteredString[10]
     + enteredString[15]
     + enteredString[6]
     + enteredString[19]
     + enteredString[29]
     + enteredString[3]
     + enteredString[8]
     + enteredString[16]
     + enteredString[28]
     + 3 * enteredString[7]
     + 2
     * (enteredString[14]
      + enteredString[17]
      + enteredString[12]
      + enteredString[9]
      + enteredString[1]
      + enteredString[25]
      + enteredString[13]) == 2956 )
    ++iResult;
  if ( enteredString[22]
     + enteredString[26]
     + enteredString[24]
     + enteredString[7]
     + enteredString[15]
     + enteredString[2]
     + enteredString[11]
     + enteredString[3]
     + enteredString[25]
     + enteredString[5]
     + enteredString[13]
     + 2 * (enteredString[20] + enteredString[21] + enteredString[12] + enteredString[18] + enteredString[8]) == 2050 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[9]
     + enteredString[11]
     + enteredString[25]
     + enteredString[5]
     + 2 * enteredString[22] == 628 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[26]
     + enteredString[20]
     + enteredString[12]
     + enteredString[2]
     + enteredString[6]
     + enteredString[29]
     + enteredString[11]
     + enteredString[3]
     + enteredString[25]
     + enteredString[5]
     + enteredString[16]
     + 2 * (enteredString[22] + enteredString[9] + enteredString[19] + 2 * enteredString[28]) == 1842 )
    ++iResult;
  if ( enteredString[24] + enteredString[10] + enteredString[9] + enteredString[11] + enteredString[16] == 491 )
    ++iResult;
  if ( enteredString[22]
     + enteredString[23]
     + enteredString[24]
     + enteredString[17]
     + enteredString[12]
     + enteredString[6]
     + enteredString[29]
     + enteredString[27]
     + enteredString[5]
     + enteredString[16]
     + enteredString[28]
     + 3 * enteredString[4]
     + 2
     * (enteredString[21]
      + enteredString[15]
      + enteredString[2]
      + enteredString[1]
      + enteredString[3]
      + enteredString[25]) == 2557 )
    ++iResult;
  if ( enteredString[26] + enteredString[7] + enteredString[27] + 3 * enteredString[2] == 474 )
    ++iResult;
  if ( enteredString[23]
     + enteredString[14]
     + enteredString[21]
     + enteredString[12]
     + enteredString[7]
     + enteredString[15]
     + enteredString[2]
     + enteredString[11]
     + enteredString[3]
     + enteredString[8]
     + 2 * (enteredString[18] + enteredString[6] + enteredString[27] + enteredString[28]) == 1472 )
    ++iResult;
  if ( enteredString[17]
     + enteredString[7]
     + enteredString[2]
     + enteredString[25]
     + enteredString[5]
     + enteredString[13]
     + 3 * enteredString[28] == 723 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[23]
     + enteredString[14]
     + enteredString[24]
     + enteredString[21]
     + enteredString[12]
     + enteredString[10]
     + enteredString[7]
     + enteredString[15]
     + enteredString[19]
     + enteredString[29]
     + enteredString[3]
     + enteredString[16]
     + 3 * (enteredString[6] + enteredString[1])
     + 2 * (enteredString[18] + enteredString[25]) == 2304 )
    ++iResult;
  if ( enteredString[20]
     + enteredString[24]
     + enteredString[17]
     + enteredString[21]
     + enteredString[10]
     + enteredString[15]
     + enteredString[2]
     + enteredString[6]
     + enteredString[1]
     + enteredString[19]
     + enteredString[3]
     + enteredString[25]
     + enteredString[8]
     + enteredString[28]
     + 3 * enteredString[12]
     + 2 * (enteredString[22] + enteredString[26] + enteredString[18] + enteredString[4]) == 2234 )
    ++iResult;
  if ( enteredString[22] + enteredString[12] + enteredString[10] + enteredString[4] + enteredString[29] == 463 )
    ++iResult;
  if ( enteredString[21] + enteredString[18] == 211 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[23]
     + enteredString[21]
     + enteredString[18]
     + enteredString[7]
     + enteredString[4]
     + enteredString[11]
     + enteredString[8]
     + enteredString[28]
     + enteredString[13]
     + 3 * enteredString[12]
     + 2 * (enteredString[26] + enteredString[9] + enteredString[29] + enteredString[27]) == 2008 )
    ++iResult;
  if ( enteredString[20]
     + enteredString[12]
     + enteredString[18]
     + enteredString[15]
     + enteredString[29]
     + enteredString[5]
     + enteredString[28]
     + 3 * enteredString[10]
     + 2 * (enteredString[14] + enteredString[25]) == 1228 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[24]
     + enteredString[21]
     + enteredString[9]
     + enteredString[4]
     + enteredString[2]
     + enteredString[1]
     + enteredString[11]
     + enteredString[3]
     + enteredString[5]
     + enteredString[8]
     + enteredString[28] == 1191 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[14]
     + enteredString[20]
     + enteredString[24]
     + enteredString[15]
     + enteredString[4]
     + enteredString[1]
     + enteredString[5]
     + enteredString[16]
     + 3 * enteredString[29]
     + 2 * (enteredString[2] + enteredString[8]) == 1691 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[23]
     + enteredString[14]
     + enteredString[17]
     + enteredString[12]
     + enteredString[10]
     + enteredString[9]
     + enteredString[15]
     + enteredString[19]
     + enteredString[3]
     + 2
     * (enteredString[21]
      + enteredString[7]
      + enteredString[1]
      + enteredString[27]
      + enteredString[8]
      + 2 * enteredString[26]) == 2070 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[17]
     + enteredString[18]
     + enteredString[10]
     + enteredString[2]
     + enteredString[19]
     + enteredString[11]
     + enteredString[28]
     + 3 * (enteredString[14] + enteredString[20] + enteredString[1])
     + 2
     * (enteredString[26] + enteredString[7]
                          + enteredString[4]
                          + enteredString[3]
                          + enteredString[25]
                          + enteredString[5]) == 2776 )
    ++iResult;
  if ( enteredString[20]
     + enteredString[10]
     + enteredString[2]
     + enteredString[1]
     + enteredString[19]
     + enteredString[11]
     + enteredString[3]
     + enteredString[27]
     + enteredString[16]
     + enteredString[28]
     + 3 * (enteredString[14] + enteredString[12])
     + 2 * (enteredString[0] + enteredString[24] + enteredString[4]) == 2169 )
    ++iResult;
  if ( enteredString[22]
     + enteredString[7]
     + enteredString[29]
     + enteredString[11]
     + enteredString[27]
     + enteredString[16]
     + enteredString[28]
     + enteredString[13]
     + 2 * (enteredString[23] + enteredString[6] + enteredString[25] + enteredString[5]) == 1394 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[14]
     + enteredString[24]
     + enteredString[21]
     + enteredString[18]
     + enteredString[4]
     + enteredString[6]
     + enteredString[29]
     + enteredString[3]
     + 3 * enteredString[2]
     + 2 * (enteredString[17] + 2 * enteredString[25]) == 1928 )
    ++iResult;
  if ( enteredString[0] + enteredString[23] + enteredString[24] + enteredString[25] + enteredString[5] == 514 )
    ++iResult;
  if ( enteredString[26]
     + enteredString[17]
     + enteredString[21]
     + enteredString[19]
     + enteredString[25]
     + enteredString[16]
     + enteredString[13] == 700 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[26]
     + enteredString[14]
     + enteredString[17]
     + enteredString[18]
     + enteredString[15]
     + enteredString[2]
     + enteredString[19]
     + enteredString[27]
     + enteredString[25]
     + enteredString[13]
     + 2 * enteredString[20] == 1184 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[23]
     + enteredString[20]
     + enteredString[24]
     + enteredString[12]
     + enteredString[15]
     + enteredString[4]
     + enteredString[29]
     + enteredString[3]
     + enteredString[5]
     + 2 * enteredString[11] == 1273 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[26]
     + enteredString[14]
     + enteredString[21]
     + enteredString[12]
     + enteredString[4]
     + enteredString[6]
     + enteredString[1]
     + enteredString[19]
     + enteredString[29]
     + enteredString[5]
     + enteredString[16] == 1192 )
    ++iResult;
  if ( enteredString[22]
     + enteredString[21]
     + enteredString[12]
     + enteredString[15]
     + enteredString[11]
     + enteredString[8]
     + enteredString[28]
     + enteredString[13]
     + 2 * enteredString[14] == 913 )
    ++iResult;
  if ( enteredString[24] + enteredString[18] + enteredString[10] + enteredString[25] + 2 * enteredString[20] == 555 )
    ++iResult;
  if ( enteredString[26] + enteredString[1] + enteredString[16] == 257 )
    ++iResult;
  if ( enteredString[12]
     + enteredString[18]
     + enteredString[7]
     + enteredString[9]
     + enteredString[15]
     + enteredString[4]
     + enteredString[3]
     + enteredString[13]
     + 2 * (enteredString[22] + enteredString[14] + enteredString[10] + enteredString[19] + enteredString[27]) == 1561 )
    ++iResult;
  if ( enteredString[20]
     + enteredString[17]
     + enteredString[18]
     + enteredString[6]
     + enteredString[1]
     + enteredString[19]
     + enteredString[29]
     + enteredString[3]
     + enteredString[13]
     + 2 * enteredString[11] == 1113 )
    ++iResult;
  if ( enteredString[20]
     + enteredString[24]
     + enteredString[10]
     + enteredString[15]
     + enteredString[6]
     + enteredString[13]
     + 2 * enteredString[22] == 589 )
    ++iResult;
  if ( enteredString[23]
     + enteredString[26]
     + enteredString[14]
     + enteredString[17]
     + enteredString[21]
     + enteredString[18]
     + enteredString[10]
     + enteredString[3]
     + enteredString[25]
     + 3 * (enteredString[4] + enteredString[19] + enteredString[27])
     + 2 * (enteredString[22] + enteredString[15] + enteredString[11]) == 2138 )
    ++iResult;
  if ( enteredString[15] + enteredString[2] + enteredString[8] == 287 )
    ++iResult;
  if ( enteredString[15]
     + enteredString[4]
     + enteredString[27]
     + enteredString[8]
     + enteredString[28]
     + 3 * enteredString[6]
     + 2 * enteredString[23] == 729 )
    ++iResult;
  if ( enteredString[0] + enteredString[2] == 199 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[23]
     + enteredString[17]
     + enteredString[10]
     + enteredString[6]
     + enteredString[19]
     + enteredString[3]
     + enteredString[25]
     + enteredString[8]
     + 3 * (enteredString[21] + enteredString[1] + enteredString[11])
     + 2 * (enteredString[22] + enteredString[14] + enteredString[12] + enteredString[29] + enteredString[5]) == 2787 )
    ++iResult;
  if ( enteredString[21]
     + enteredString[10]
     + enteredString[7]
     + enteredString[9]
     + enteredString[4]
     + enteredString[19]
     + enteredString[11]
     + enteredString[3]
     + enteredString[28]
     + 2 * enteredString[2] == 1071 )
    ++iResult;
  if ( enteredString[14]
     + enteredString[20]
     + enteredString[18]
     + enteredString[15]
     + enteredString[6]
     + enteredString[11]
     + enteredString[3]
     + enteredString[25]
     + enteredString[8]
     + enteredString[13] == 958 )
    ++iResult;
  if ( enteredString[10] + enteredString[4] + enteredString[16] + 2 * enteredString[8] == 477 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[17]
     + enteredString[9]
     + enteredString[15]
     + enteredString[4]
     + enteredString[3]
     + enteredString[27]
     + enteredString[8]
     + 3 * enteredString[28]
     + 2
     * (enteredString[14]
      + enteredString[20]
      + enteredString[7]
      + enteredString[2]
      + enteredString[6]
      + enteredString[16]) == 2015 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[26]
     + enteredString[14]
     + enteredString[20]
     + enteredString[10]
     + enteredString[7]
     + enteredString[15]
     + enteredString[1]
     + enteredString[27]
     + enteredString[28]
     + 2 * (enteredString[21] + enteredString[18] + enteredString[2] + enteredString[29]) == 1679 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[22]
     + enteredString[20]
     + enteredString[24]
     + enteredString[7]
     + enteredString[15]
     + enteredString[19]
     + enteredString[11]
     + enteredString[3]
     + enteredString[27]
     + enteredString[5]
     + enteredString[16]
     + enteredString[13]
     + 3 * enteredString[14]
     + 2 * (enteredString[12] + enteredString[10] + enteredString[4] + enteredString[25] + enteredString[28]) == 2404 )
    ++iResult;
  if ( enteredString[12]
     + enteredString[18]
     + enteredString[1]
     + enteredString[29]
     + enteredString[8]
     + enteredString[28]
     + 3 * enteredString[13]
     + 2
     * (enteredString[0]
      + enteredString[21]
      + enteredString[10]
      + enteredString[15]
      + enteredString[4]
      + enteredString[6]
      + enteredString[19]
      + enteredString[11]
      + enteredString[27]) == 2453 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[26]
     + enteredString[14]
     + enteredString[20]
     + enteredString[7]
     + enteredString[9]
     + enteredString[1]
     + enteredString[29]
     + enteredString[11]
     + enteredString[27]
     + enteredString[5]
     + enteredString[16]
     + enteredString[13]
     + 2 * (enteredString[17] + enteredString[3] + enteredString[28]) == 1722 )
    ++iResult;
  if ( enteredString[12]
     + enteredString[18]
     + enteredString[7]
     + enteredString[15]
     + enteredString[4]
     + enteredString[2]
     + enteredString[6]
     + enteredString[1]
     + 3 * (enteredString[5] + enteredString[13])
     + 2
     * (enteredString[22]
      + enteredString[26]
      + enteredString[10]
      + enteredString[3]
      + enteredString[27]
      + enteredString[28]) == 1971 )
    ++iResult;
  if ( enteredString[11] + enteredString[28] == 141 )
    ++iResult;
  if ( enteredString[22]
     + enteredString[14]
     + enteredString[17]
     + enteredString[10]
     + enteredString[1]
     + enteredString[27]
     + 3 * (enteredString[20] + enteredString[7])
     + 2 * (enteredString[18] + enteredString[4] + enteredString[19] + enteredString[25] + enteredString[13]) == 2184 )
    ++iResult;
  if ( enteredString[24]
     + enteredString[17]
     + enteredString[21]
     + enteredString[10]
     + enteredString[7]
     + enteredString[2]
     + enteredString[29]
     + enteredString[11]
     + enteredString[3]
     + enteredString[25]
     + enteredString[16]
     + 3 * (enteredString[22] + enteredString[14])
     + 2
     * (enteredString[0]
      + enteredString[18]
      + enteredString[15]
      + enteredString[1]
      + enteredString[19]
      + enteredString[8]) == 2825 )
    ++iResult;
  if ( enteredString[17] + enteredString[9] + enteredString[2] + enteredString[3] + enteredString[5] == 508 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[14]
     + enteredString[24]
     + enteredString[21]
     + enteredString[12]
     + enteredString[9]
     + enteredString[1]
     + enteredString[19]
     + enteredString[29]
     + enteredString[28]
     + 3 * (enteredString[18] + enteredString[13])
     + 2 * enteredString[16] == 1861 )
    ++iResult;
  if ( enteredString[20]
     + enteredString[15]
     + enteredString[29]
     + enteredString[11]
     + enteredString[27]
     + enteredString[16]
     + enteredString[13] == 673 )
    ++iResult;
  if ( enteredString[23]
     + enteredString[24]
     + enteredString[17]
     + enteredString[21]
     + enteredString[18]
     + enteredString[9]
     + enteredString[15]
     + enteredString[4]
     + enteredString[19]
     + enteredString[3]
     + enteredString[16]
     + 3 * enteredString[29]
     + 2 * (enteredString[11] + enteredString[27] + enteredString[28] + 2 * enteredString[5]) == 2269 )
    ++iResult;
  if ( enteredString[22] + enteredString[6] + enteredString[25] + enteredString[8] == 308 )
    ++iResult;
  if ( enteredString[24]
     + enteredString[12]
     + enteredString[7]
     + enteredString[15]
     + enteredString[6]
     + enteredString[5]
     + enteredString[8]
     + enteredString[16]
     + 2 * enteredString[9] == 1012 )
    ++iResult;
  if ( enteredString[14] + enteredString[16] == 216 )
    ++iResult;
  if ( enteredString[0]
     + enteredString[24]
     + enteredString[17]
     + enteredString[21]
     + enteredString[12]
     + enteredString[7]
     + enteredString[9]
     + enteredString[6]
     + enteredString[1]
     + enteredString[27]
     + enteredString[16]
     + enteredString[13]
     + 3 * enteredString[8]
     + 2 * (enteredString[26] + enteredString[14] + enteredString[4] + enteredString[2] + enteredString[28]) == 2237 )
    ++iResult;
  if ( enteredString[23]
     + enteredString[20]
     + enteredString[15]
     + enteredString[4]
     + enteredString[6]
     + enteredString[1]
     + enteredString[27]
     + 3 * enteredString[10]
     + 2 * enteredString[12] == 985 )
    ++iResult;
  str_Result_Msg[5] = ' ';
  if ( iResult == 0x64 )
  {
    str_Result_Msg[0] = 'T';
    str_Result_Msg[1] = 'h';
    str_Result_Msg[2] = 'a';
    str_Result_Msg[3] = 't';
    str_Result_Msg[4] = 's';
    str_Result_Msg[6] = 'i';
    str_Result_Msg[7] = 't';
    str_Result_Msg[8] = '!';
    str_Result_Msg[9] = '!';
    str_Result_Msg[10] = '\0';
    puts(str_Result_Msg);
  }
  else
  {
    str_Result_Msg[0] = 'N';
    str_Result_Msg[1] = 'o';
    str_Result_Msg[2] = 'p';
    str_Result_Msg[3] = 'e';
    str_Result_Msg[4] = ',';
    str_Result_Msg[6] = 'T';
    str_Result_Msg[7] = 'r';
    str_Result_Msg[8] = 'y';
    str_Result_Msg[9] = ' ';
    str_Result_Msg[10] = 'a';
    str_Result_Msg[11] = 'g';
    str_Result_Msg[12] = 'a';
    str_Result_Msg[13] = 'i';
    str_Result_Msg[14] = 'n';
    str_Result_Msg[15] = ' ';
    str_Result_Msg[16] = ';';
    str_Result_Msg[17] = ')';
    str_Result_Msg[18] = '\0';
    puts(str_Result_Msg);
  }
  ((void (__stdcall *)(signed int))addr_Sleep)(750);
  return 0;
}

Để trích xuất ra các vùng code tính toán mà không bị lẫn các đoạn code encrypt/decrypt, thực hiện script sau để loại bỏ:

/* IDC Script: this script used to finds both encryption and decryption loops and just nops them out*/
//declare local variables
auto ea;
auto addr;
auto size;
auto xorval;
auto x;
auto b;
 
ea = MinEA();
ea = FindBinary(ea, SEARCH_DOWN , "60 E8 00 00 00 00 5E 81");
while (ea != BADADDR)
{
   for (x=0;x<0x1C;x++)
   {
      PatchByte(ea+x, 0x90);
   }
   MakeUnknown(ea, 0x1C, 0);  //undefine the specified
   MakeCode(ea);  //convert to instruction
   ea = FindBinary(ea +1, SEARCH_DOWN , "60 E8 00 00 00 00 5E 81");
}   

Script này được chỉnh lại từ script trên, đơn giản là thực hiện tìm kiếm cả encryption và decryption loops và nop toàn bộ code liên quan. Sau đó, buộc IDA thực hiện phân tích lại vùng code đã patched.

2015-11-05_12-08-17Sau khi Script thực hiện xong, mã giả có được bằng HexRays sẽ như sau:

2015-11-05_12-16-22Sau khi có được thông tin toàn bộ mã giả tử HexRays, sử dụng trình Editor (ở đây tôi dùng Notepad++) để thực hiện lấy toàn bộ thông tin của các vùng code tính toán:

  • Loại bỏ toàn bộ dấu cách thừa bằng cách thay thế 2 dấu cách (”  “) bằng 1 dấu cách (” “). Lặp lại cho đến khi hết thì thôi. Ta có được kết quả tương tự như sau:

2015-11-05_15-48-02

  • Đặt mỗi phép tính trên một dòng bằng cách thay thế “\r\n +” (new line,space,plus) với ” +” (space,plus) và thay thế “\r\n *” (new line,space,star) bằng ” *” (space,star). Ta có được tương tự như sau:

2015-11-05_15-54-01

  • Loại bỏ các lệnh “if”. Loại bỏ các lệnh “++iResult;”. Thay thế “==” với “=”. Kết quả như sau:

2015-11-05_15-59-46

  • Cuối cùng, đổi tên biến “enteredString” thành biến “z” và loại bỏ các “[”“]”, “( ”“ )”. Cuối cùng có được code như sau:
 z0 + z22 + z26 + z20 + z10 + z7 + 3 * z14 + 2 * (z23 + z24 + z17 + z21 + z12 + z18) = 2024
 z0 + z22 + z23 + z26 + z14 + z24 + z17 + z12 + z10 + z15 + z4 + z2 + z6 + z1 + z29 + z11 + 2 * (z9 + z19) = 1927 
 z14 + z10 = 148 
 z0 + z14 + z10 + z11 + z3 + z25 + 2 * (z22 + z27) = 741 
 z24 + z29 = 229 
 z0 + z26 + z20 + z21 + z12 + z7 + z9 + z15 + z4 + z1 + z29 + z11 + z3 + z27 + z25 + z5 + z8 + z16 + 2 * (z6 + z19) = 2133 
 z14 + z17 + z7 + z15 + z11 + z8 = 619 
 z0 + z22 + z26 + z21 + z12 + z7 + z11 + z16 + z28 + 2 * z23 = 996 
 z24 + z17 + z6 + z1 + z29 + 2 * z21 = 717 
 z24 + z21 + z12 + z18 + z6 + z29 + z11 + z8 + z16 + 3 * z26 + 2 * (z0 + z17 + z2 + z19 + z5 + z28 + z13) = 2308 
 z20 + z17 + z21 + z7 + z9 + z1 + z19 + z11 + z27 + z8 + z28 + 3 * (z14 + z3) + 2 * (z0 + z23 + z18 + z6) = 2347 
 z0 + z26 + z20 + z24 + z10 + z9 + z6 + z11 + z25 + 2 * (z23 + z28) = 1041 
 z23 + z6 + z27 = 184 
 z23 + z18 + z9 + z19 + z11 + z25 + z5 + z16 + 2 * z1 = 1076 
 z0 + z22 + z26 + z20 + z24 + z10 + z7 + z4 + z2 + z6 + z19 + z11 = 1040 
 z0 + z22 + z23 + z14 + z18 + z10 + z4 + z6 + z1 + z19 + z11 + z8 + z16 + z28 + 5 * z21 + 3 * z13 + 2 * (z26 + z24) = 2393 
 z0 + z23 + z26 + z24 + z9 + z15 + z29 + z11 + z25 = 901 
 z0 + z22 + z18 + z10 + z7 + z9 + z29 + z11 + z28 + 3 * z26 = 893 
 z18 + z11 + z3 = 308 
 z22 + z14 + z20 + z12 + z10 + z4 + z2 + z19 + z29 + z5 + z8 + z13 + 2 * z18 = 1350 
 z0 + z26 + z14 + z20 + z17 + z7 + z9 + z1 + z19 + z5 + z8 + 2 * (z15 + z29 + z28) = 1580 
 z14 + z20 + z24 + z12 + z18 + z10 + z15 + z6 + z29 + z3 + z25 + 3 * z21 + 2 * (z0 + z7 + z4) = 2075 
 z23 + z26 + z24 + z17 + z21 + z18 + z10 + z6 + z11 + z5 + z8 + z13 + 3 * z22 + 2 * (z7 + z9 + z27) = 1721 
 z11 + z28 = 141 
 z26 + z24 + z17 + z12 + z7 + z4 + z29 + z5 + z16 + z13 + 2 * (z22 + z15 + z25) = 1550 
 z0 + z22 + z20 + z17 + z18 + z15 + z2 + z1 + z19 + z27 + z5 + z16 + z13 + 2 * (z14 + z24 + z10 + z7 + z6 + z11 + z25) = 2484 
 z22 + z17 + z10 + z5 + z16 + 2 * (z20 + z24) = 804 
 z7 + z4 + z2 + z27 + z25 + z5 + z8 + z16 + z13 + 3 * (z22 + z24 + z9) + 2 * (z0 + z1 + z28 + 2 * z10) = 2369 
 z23 + z17 + z12 + z27 + z16 + 2 * z9 = 704 
 z0 + z26 + z24 + z10 + z7 + z4 + z6 + z1 + z29 + z11 + z3 + z27 + z5 + z8 + z13 + 3 * z20 + 2 * (z22 + z14 + z15) = 2110 
 z26 + z14 + z21 + z18 + z9 + z15 + z2 + z29 + z3 + z5 = 968 
 z24 + z12 + z4 + z1 + z19 + z3 + z16 + 2 * (z26 + z21 + z6 + z5) = 1356 
 z0 + z22 + z21 + z9 + z15 + z29 + z3 + z5 + 3 * z23 + 2 * (z12 + z7 + z19 + z27) = 1869 
 z26 + z14 + z18 + z7 + z9 + z2 + z1 + z3 + z5 + z8 + z28 + 2 * (z0 + z20 + z17 + z21 + z15 + z6 + z19 + z25 + z13) = 2769 
 z22 + z23 + z10 + z15 + z19 + z11 + z8 + z28 + 2 * (z0 + z24 + z1 + z3 + z27 + 2 * (z26 + z7)) = 2147 
 z23 + z14 + z20 + z24 + z17 + z19 + z11 + z3 + z25 + z13 + 2 * (z0 + z21 + z9 + z2 + z6 + z1 + z16) = 2450 
 z0 + z26 + z24 + z17 + z21 + z18 + z10 + z9 + z19 + z27 + z25 + 3 * (z11 + z13) + 2 * (z12 + z28 + 2 * (z1 + z3)) = 2755 
 z0 + z23 + z26 + z20 + z21 + z12 + z7 + z9 + z2 + z1 + z11 + z5 + z16 + 3 * (z6 + z25) + 2 * (z24 + z18 + z10 + z15 + z28) = 2561 
 z21 + z4 + z19 + z5 + 2 * z14 = 642 
 z20 + z24 + z17 + z4 + z27 + z25 + z8 + z16 + 3 * z19 + 2 * (z26 + z14 + z7 + z13 + 2 * z29) = 2336 
 z20 + z24 + z12 + z18 + z10 + 3 * z3 + 2 * (z17 + z21 + z9 + z15 + z2 + z1 + z19 + z29 + z11 + z8) = 2925 
 z23 + z20 + z24 + z10 + z15 + z6 + z19 + z29 + z3 + z8 + z16 + z28 + 3 * z7 + 2 * (z14 + z17 + z12 + z9 + z1 + z25 + z13) = 2956 
 z22 + z26 + z24 + z7 + z15 + z2 + z11 + z3 + z25 + z5 + z13 + 2 * (z20 + z21 + z12 + z18 + z8) = 2050 
 z0 + z9 + z11 + z25 + z5 + 2 * z22 = 628 
 z0 + z26 + z20 + z12 + z2 + z6 + z29 + z11 + z3 + z25 + z5 + z16 + 2 * (z22 + z9 + z19 + 2 * z28) = 1842 
 z24 + z10 + z9 + z11 + z16 = 491 
 z22 + z23 + z24 + z17 + z12 + z6 + z29 + z27 + z5 + z16 + z28 + 3 * z4 + 2 * (z21 + z15 + z2 + z1 + z3 + z25) = 2557 
 z26 + z7 + z27 + 3 * z2 = 474 
 z23 + z14 + z21 + z12 + z7 + z15 + z2 + z11 + z3 + z8 + 2 * (z18 + z6 + z27 + z28) = 1472 
 z17 + z7 + z2 + z25 + z5 + z13 + 3 * z28 = 723 
 z0 + z22 + z23 + z14 + z24 + z21 + z12 + z10 + z7 + z15 + z19 + z29 + z3 + z16 + 3 * (z6 + z1) + 2 * (z18 + z25) = 2304 
 z20 + z24 + z17 + z21 + z10 + z15 + z2 + z6 + z1 + z19 + z3 + z25 + z8 + z28 + 3 * z12 + 2 * (z22 + z26 + z18 + z4) = 2234 
 z22 + z12 + z10 + z4 + z29 = 463 
 z21 + z18 = 211 
 z0 + z22 + z23 + z21 + z18 + z7 + z4 + z11 + z8 + z28 + z13 + 3 * z12 + 2 * (z26 + z9 + z29 + z27) = 2008 
 z20 + z12 + z18 + z15 + z29 + z5 + z28 + 3 * z10 + 2 * (z14 + z25) = 1228 
 z0 + z24 + z21 + z9 + z4 + z2 + z1 + z11 + z3 + z5 + z8 + z28 = 1191 
 z0 + z14 + z20 + z24 + z15 + z4 + z1 + z5 + z16 + 3 * z29 + 2 * (z2 + z8) = 1691 
 z0 + z23 + z14 + z17 + z12 + z10 + z9 + z15 + z19 + z3 + 2 * (z21 + z7 + z1 + z27 + z8 + 2 * z26) = 2070 
 z0 + z17 + z18 + z10 + z2 + z19 + z11 + z28 + 3 * (z14 + z20 + z1) + 2 * (z26 + z7 + z4 + z3 + z25 + z5) = 2776 
 z20 + z10 + z2 + z1 + z19 + z11 + z3 + z27 + z16 + z28 + 3 * (z14 + z12) + 2 * (z0 + z24 + z4) = 2169 
 z22 + z7 + z29 + z11 + z27 + z16 + z28 + z13 + 2 * (z23 + z6 + z25 + z5) = 1394 
 z0 + z22 + z14 + z24 + z21 + z18 + z4 + z6 + z29 + z3 + 3 * z2 + 2 * (z17 + 2 * z25) = 1928 
 z0 + z23 + z24 + z25 + z5 = 514 
 z26 + z17 + z21 + z19 + z25 + z16 + z13 = 700 
 z0 + z26 + z14 + z17 + z18 + z15 + z2 + z19 + z27 + z25 + z13 + 2 * z20 = 1184 
 z0 + z23 + z20 + z24 + z12 + z15 + z4 + z29 + z3 + z5 + 2 * z11 = 1273 
 z0 + z26 + z14 + z21 + z12 + z4 + z6 + z1 + z19 + z29 + z5 + z16 = 1192 
 z22 + z21 + z12 + z15 + z11 + z8 + z28 + z13 + 2 * z14 = 913 
 z24 + z18 + z10 + z25 + 2 * z20 = 555 
 z26 + z1 + z16 = 257 
 z12 + z18 + z7 + z9 + z15 + z4 + z3 + z13 + 2 * (z22 + z14 + z10 + z19 + z27) = 1561 
 z20 + z17 + z18 + z6 + z1 + z19 + z29 + z3 + z13 + 2 * z11 = 1113 
 z20 + z24 + z10 + z15 + z6 + z13 + 2 * z22 = 589 
 z23 + z26 + z14 + z17 + z21 + z18 + z10 + z3 + z25 + 3 * (z4 + z19 + z27) + 2 * (z22 + z15 + z11) = 2138 
 z15 + z2 + z8 = 287 
 z15 + z4 + z27 + z8 + z28 + 3 * z6 + 2 * z23 = 729 
 z0 + z2 = 199 
 z0 + z23 + z17 + z10 + z6 + z19 + z3 + z25 + z8 + 3 * (z21 + z1 + z11) + 2 * (z22 + z14 + z12 + z29 + z5) = 2787 
 z21 + z10 + z7 + z9 + z4 + z19 + z11 + z3 + z28 + 2 * z2 = 1071 
 z14 + z20 + z18 + z15 + z6 + z11 + z3 + z25 + z8 + z13 = 958 
 z10 + z4 + z16 + 2 * z8 = 477 
 z0 + z17 + z9 + z15 + z4 + z3 + z27 + z8 + 3 * z28 + 2 * (z14 + z20 + z7 + z2 + z6 + z16) = 2015 
 z0 + z22 + z26 + z14 + z20 + z10 + z7 + z15 + z1 + z27 + z28 + 2 * (z21 + z18 + z2 + z29) = 1679 
 z0 + z22 + z20 + z24 + z7 + z15 + z19 + z11 + z3 + z27 + z5 + z16 + z13 + 3 * z14 + 2 * (z12 + z10 + z4 + z25 + z28) = 2404 
 z12 + z18 + z1 + z29 + z8 + z28 + 3 * z13 + 2 * (z0 + z21 + z10 + z15 + z4 + z6 + z19 + z11 + z27) = 2453 
 z0 + z26 + z14 + z20 + z7 + z9 + z1 + z29 + z11 + z27 + z5 + z16 + z13 + 2 * (z17 + z3 + z28) = 1722 
 z12 + z18 + z7 + z15 + z4 + z2 + z6 + z1 + 3 * (z5 + z13) + 2 * (z22 + z26 + z10 + z3 + z27 + z28) = 1971 
 z11 + z28 = 141 
 z22 + z14 + z17 + z10 + z1 + z27 + 3 * (z20 + z7) + 2 * (z18 + z4 + z19 + z25 + z13) = 2184 
 z24 + z17 + z21 + z10 + z7 + z2 + z29 + z11 + z3 + z25 + z16 + 3 * (z22 + z14) + 2 * (z0 + z18 + z15 + z1 + z19 + z8) = 2825 
 z17 + z9 + z2 + z3 + z5 = 508 
 z0 + z14 + z24 + z21 + z12 + z9 + z1 + z19 + z29 + z28 + 3 * (z18 + z13) + 2 * z16 = 1861 
 z20 + z15 + z29 + z11 + z27 + z16 + z13 = 673 
 z23 + z24 + z17 + z21 + z18 + z9 + z15 + z4 + z19 + z3 + z16 + 3 * z29 + 2 * (z11 + z27 + z28 + 2 * z5) = 2269 
 z22 + z6 + z25 + z8 = 308 
 z24 + z12 + z7 + z15 + z6 + z5 + z8 + z16 + 2 * z9 = 1012 
 z14 + z16 = 216 
 z0 + z24 + z17 + z21 + z12 + z7 + z9 + z6 + z1 + z27 + z16 + z13 + 3 * z8 + 2 * (z26 + z14 + z4 + z2 + z28) = 2237 
 z23 + z20 + z15 + z4 + z6 + z1 + z27 + 3 * z10 + 2 * z12 = 985 

Với một hệ phương trình tuyến tính rối rắm có được như trên, nghĩ ngồi để giải được cái đồng phương trình này chắc chết sexy_girl. May mắn thay có một site hỗ trợ giải phương trình online tại: http://wims.unice.fr/wims/en_tool~linear~linsolver.en.html. Truy cập vào trang Web và paste toàn bộ đoạn code trên vào, sau đó nhấn “Solve the problem”:

2015-11-05_16-14-09Kết quả, có được như sautoo_sad:

2015-11-05_16-16-27Cụ thể:

{ z0 = 102, z1 = 108, z10 = 48, z11 = 108, z12 = 118, z13 = 101, z14 = 100, z15 = 95, z16 = 116, z17 = 104, z18 = 97, z19 = 116, z2 = 97, z20 = 95, z21 = 114, z22 = 49, z23 = 103, z24 = 104, z25 = 116, z26 = 33, z27 = 33, z28 = 33, z29 = 125, z3 = 103, z4 = 123, z5 = 89, z6 = 48, z7 = 117, z8 = 95, z9 = 115 }.

Chuyển đổi toàn bộ kết quả trên trên thành kí tự tương ứng sẽ có được flag cần tìm. Code bằng Python:

asscii=[102, 108, 97, 103, 123, 89, 48, 117, 95, 115, 48, 108, 118, 101, 100, 95, 116, 104, 97, 116, 95, 114, 49, 103, 104, 116, 33, 33, 33, 125]
flag = "".join([chr(c) for c in asscii])

print flag

Kết quả có được Flag: flag{Y0u_s0lved_that_r1ght!!!}.Kiểm tra kết quả:

2015-11-05_16-55-38End..

[IDA Plugin] IDA Stingray

Posted: October 9, 2015 in IDA Stingray
Tags: ,

stingray
Tác giả: darx0r

Site: https://github.com/darx0r/Stingray

Sơ lược:

Stingray là một IDAPython plugin, tính năng chính của plugin này tìm kiếm các chuỗi (strings) có trong hàm, hỗ trợ thực hiện tìm kiếm đệ quy thông qua khả năng cho phép cấu hình độ sâu của việc tìm kiếm. Đối với mỗi string được tìm thấy sẽ được hiển thị thêm thông tin về địa chỉ xrefs (địa chỉ sử dụng string), địa chỉ của chuỗi, kiểu chuỗi (string type).

Yêu cầu cài đặt:

Phải sử dụng IDA (Hex Rays Interactive Disassembler) có phiên bản >= 6 cùng với IDAPython.

Sử dụng:

Chép file Stingray.py vào thư mục chứa Plugin của IDA. Nếu thành công, khi khởi động IDA và phân tích target, Stingray sẽ xuất hiện tại : Edit/Plguins/Stingray. Mặc định Stingray đã được tác giả cấu hình với độ sâu tìm kiếm là 0 (không sử dụng tìm kiếm đệ quy) và phím tắt của plugin là Shift+S. Tuy nhiên, có thể cấu hình lại Stingray bất kỳ lúc nào thông qua Options\Stingray Config . Nếu không muốn tìm kiếm đệ quy, cấu hình lại chế độ search. lựa chọn độ sâu là 0.

StingrayHình minh họa


Tải crackme tại: http://crackmes.de/users/san01suke/somecrypto02/

Bài viết tham khảo write-up của Johannesbade , tại : http://johannesbader.ch/2014/07/crackmes-de-san01sukes-somecrypto02/

1.Patch file để lấy full code

Giao diện của crackme khi thực thi tương tự như SomeCrypto~01:
01

Load crackme vào OllyDBG. Tại EP có được code như sau:
02

Quan sát, nhận thấy có hai điểm khá thú vị:

  • Vùng code trước 0x4014D3 không thể disassembly được và trông giống như đã bị làm rối (obfuscated).
  • Vùng code sau EP rõ ràng sẽ làm thay đổi code của crackme. Bắt đầu tại vị trí 0x401000, lệnh XOR được sử dụng để XOR chính xác 0x4D3 bytes (lưu tại ecx) với giá trị 0x20h (lưu tại al).

Vùng code tại 0x401000 trước khi thay đổi:

03

Nhấn F8 để trace thử một vài lần sẽ thấy được các bytes đã được thay đổi:

04

Để có đầy đủ các byte sau khi XOR, đặt BP tại lệnh 004014EF   . FFD0       call   eax, sau đó nhấn F9, break tại BP. Lúc này đã có toàn bộ code sau khi XOR, nhưng OllyDbg không tự động phân tích lại và vẫn hiển thị các bytes. Nhấn Ctrl + A để phân tích lại code sẽ có được đầy đủ thông tin:

05

Lưu lại bản patched của crackme sau khi các bytes từ 0x401000 tới 0x4014D2 đã được XOR với 20h (Dump file và sửa lại EP của file mới thành 0x14B0). Sau đó, sử dụng IDA Pro để load file mới:

06

2. Phân tích sub_4011E0 – lần 1

Mở Subviews Strings (Shift + F12), quan sát thấy có chuỗi “Success”:

07

Tìm tới đoạn code liên quan tới chuỗi này:

08

Theo đoạn code trong hình, ta sẽ nhận được thông báo “Success” nếu sub_4011E0 trả về một giá trị khác 0 tại thanh ghi eax. Tiến hành phân tích sub_4011E0:

09

Theo thông tin cung cấp khi debug với OllyDBG, ta thấy rằng thanh ghi edi sẽ chứa chuỗi szSerial mà ta nhập vào:

10

Quan sát đoạn mã tại loc_401296:

11

Với thông tin có được, chuyển sang mã giả ta như sau:

serial = edi
IF strlen(serial) == 0 THEN
    RETURN 0 // loc_401296
END

Nếu có nhập serial (serial không phải là chuỗi rỗng) thì đoạn mã tiếp theo được thực hiện:

12

Đoạn mã trên thực hiện tính toán chiều dài của serial và trả về 0 nếu không phải là 7. Ta có mã giả như sau:

serial_length = strlen(serial)
IF serial_length != 7 THEN
    RETURN 0 // loc_401296
END

Nếu chiều dài nhập vào lớn hơn 7, đoạn mã tiếp theo sẽ thực hiện lời gọi tới một subroutine khác:

13

eax là một biến cục bộ. Vùng bộ nhớ ebp+arg_0 = ebp+8 trỏ đến nội dung của Name textbox, kiểm tra bằng OllyDbg ta có được:

14

var_1C là biến mà chưa biết kiểu, mã giả có được như sau:

sub_401000(&var_1C, szName)

3. Phân tích sub_401000

Chuyển tới sub_401000, toàn bộ code tại đây như sau:

.text:00401000 ; =============== S U B R O U T I N E =======================================
.text:00401000
.text:00401000
.text:00401000 ; int __usercall sub_401000@<eax>(int mapping@<eax>, int szName@<edx>)
.text:00401000 sub_401000      proc near               ; CODE XREF: sub_4011E0+26p
.text:00401000                 mov     dword ptr [eax], 0 ; mapping[0] = 0x0
.text:00401006                 mov     dword ptr [eax+4], 1 ; mapping[4] = 0x1
.text:0040100D                 mov     dword ptr [eax+8], 2 ; mapping[8] = 0x2
.text:00401014                 mov     dword ptr [eax+0Ch], 3 ; mapping[12] = 0x3
.text:0040101B                 mov     dword ptr [eax+10h], 4 ; mapping[16] = 0x4
.text:00401022                 mov     dword ptr [eax+14h], 5 ; mapping[20] = 0x5
.text:00401029                 mov     dword ptr [eax+18h], 6 ; mapping[24] = 0x6
.text:00401030                 mov     cl, [edx]
.text:00401032                 test    cl, cl          ; if szName[i] is null
.text:00401034                 jz      short locret_40108C ; then exit sub
.text:00401036                 push    esi             ; save esi
.text:00401037                 jmp     short top_Loop
.text:00401037 ; ---------------------------------------------------------------------------
.text:00401039                 align 10h
.text:00401040
.text:00401040 top_Loop:                               ; CODE XREF: sub_401000+37j
.text:00401040                                         ; sub_401000+89j
.text:00401040                 movsx   ecx, cl         ; Temp = szName[i]
.text:00401043                 and     ecx, 80000001h  ; Temp &= 0x80000001; set SF = 1 if result is 80000000h
.text:00401049                 jns     short swap_mapping ; if Temp != 0 then swap(mapping[0], mapping[4])
.text:0040104B                 dec     ecx
.text:0040104C                 or      ecx, 0FFFFFFFEh
.text:0040104F                 inc     ecx
.text:00401050
.text:00401050 swap_mapping:                           ; CODE XREF: sub_401000+49j
.text:00401050                 jz      short rotate_left ; if Temp = 0 then rotate_left_mapping
.text:00401052                 mov     esi, [eax+4]    ; \
.text:00401055                 mov     ecx, [eax]      ; |<- swap(mapping[0], mapping[4])
.text:00401057                 mov     [eax], esi      ; |
.text:00401059                 mov     [eax+4], ecx    ; /
.text:0040105C
.text:0040105C rotate_left:                            ; CODE XREF: sub_401000:swap_mappingj
.text:0040105C                 mov     ecx, [eax]      ; ecx = mapping[0]
.text:0040105E                 mov     esi, [eax+4]
.text:00401061                 mov     [eax], esi      ; mapping[0] = mapping[4]
.text:00401063                 mov     esi, [eax+8]
.text:00401066                 mov     [eax+4], esi    ; mapping[4] = mapping[8]
.text:00401069                 mov     esi, [eax+0Ch]
.text:0040106C                 mov     [eax+8], esi    ; mapping[8] = mapping[12]
.text:0040106F                 mov     esi, [eax+10h]
.text:00401072                 mov     [eax+0Ch], esi  ; mapping[12] = mapping[16]
.text:00401075                 mov     esi, [eax+14h]
.text:00401078                 mov     [eax+10h], esi  ; mapping[16] = mapping[20]
.text:0040107B                 mov     esi, [eax+18h]
.text:0040107E                 mov     [eax+14h], esi  ; mapping[20] = mapping[24]
.text:00401081                 inc     edx
.text:00401082                 mov     [eax+18h], ecx  ; mapping[24] = ecx
.text:00401085                 mov     cl, [edx]       ; cl = next char of szName
.text:00401087                 test    cl, cl          ; if not null
.text:00401089                 jnz     short top_Loop  ; continue Loop
.text:0040108B                 pop     esi             ; restore esi
.text:0040108C
.text:0040108C locret_40108C:                          ; CODE XREF: sub_401000+34j
.text:0040108C                 retn
.text:0040108C sub_401000      endp
.text:0040108C

Phân tích subroutine từ đầu tới cuối có được thông tin như sau:

  • Khởi tạo một mảng, tạm đặt tên là mapping[] và gán các giá trị cho mảng: {0,1,2,3,4,5,6}
  • Kiểm tra từng kí tự trong chuỗi szName nhập vào theo biểu thức: Temp &= 0x80000001 (với Temp = szName[i])
    • Nếu Temp != 0, thực hiện đổi vị trí hai giá trị đầu tiên của mảng. Ví dụ, sau khi đổi sẽ là {0,1,2,3,4,5,6} -> {0,1,2,3,4,5,6}
    • Nếu Temp = 0, thực hiện việc gán lại các giá trị trong mảng theo kiểu dịch trái quay vòng. Ví dụ, sau khi thực hiện sẽ có {0,1,2,3,4,5,6} -> {0,1,2,3,4,5,6}
  • Lặp lại cho đến khi hết chuỗi szName, kết quả trả về là mảng mapping[] sau khi thực hiện các phép hoán đối và gán lại.

Mã giả của sub_401000 có được như sau:

FUNCTION sub_401000(mapping<var_1C>, szName)
    mapping = {0,1,2,3,4,5,6} // in eax = &var_1C
    FOR character IN szName DO
        IF character % 2 != 0 DO
            swap(mapping[0], mapping[1])
        ENDIF
        circular_left_shift(mapping)
    ENDFOR
    RETURN mapping
END

4. Phân tích sub_4011E0 – lần 2

Phân tích xong sub_401000, quay trở lại sub_4011E0 để phân tích tiếp các lệnh bên dưới:

15

Đoạn code này đơn giản thực hiện việc copy chuỗi mặc định của crackme tại địa chỉ byte_403010 (hardcoded_str) tới byte_403140 (copy_hardcoded_str). Sau đó kiểm tra xem chuỗi sau khi copy có null hay không? (Điều kiện này hơi thừa vì đã copy vào rồi thì null thế nào được🙂 ). Mã giả của đoạn code trên như sau:

STRCPY(byte_403140, byte_403010) // copy string byte_403010 to byte_403140
IF byte_403140 == NULL THEN
    GOTO loc_40123A \\ should never happen
ENDIF

Chuỗi hardcoded ban đầu của crackme tại địa chỉ byte_403010 như hình bên dưới:

16

Tiếp theo là một vòng lặp nhỏ khác:

17

Vòng lặp này thực hiện duyệt toàn bộ chuỗi sau khi copy tại byte_403140 (copy_hardcoded_str) cho tới khi gặp null và tăng dần thanh ghi esi. Kết thúc vòng lặp thì giá trị có được của thanh ghi esi chính là độ dài của chuỗi tại byte_403140, ta có mã giả như sau:

esi = strlen(byte_403140)

Đoạn code tiếp theo sẽ là lời gọi tới một subroutine khác với hai tham số truyền vào là var_1Cstrlen(byte_403140):

18

Trong đó, tham số var_1C chính là mảng mapping[] đã phân tích ở trên, chứa các giá trị từ 0 đến 6 đã được trộn lại bởi sub_401000.

5. Phân tích sub_401110

.text:00401110 ; =============== S U B R O U T I N E =======================================
.text:00401110 ; Attributes: bp-based frame
.text:00401110 ; _UNKNOWN *__userpurge sub_401110@<eax>(_UNKNOWN *result@<eax>, int len_copy_hardcoded)
.text:00401110 sub_401110      proc near               ; CODE XREF: sub_4011E0+5Ep
.text:00401110                                         ; sub_4011E0+71p
.text:00401110
.text:00401110 var_1C          = dword ptr -1Ch
.text:00401110 var_18          = word ptr -18h
.text:00401110 var_16          = byte ptr -16h
.text:00401110 var_14          = dword ptr -14h
.text:00401110 var_10          = dword ptr -10h
.text:00401110 var_C           = dword ptr -0Ch
.text:00401110 var_8           = dword ptr -8
.text:00401110 var_4           = dword ptr -4
.text:00401110 len_copy_hardcoded= dword ptr  8
.text:00401110
.text:00401110                 push    ebp
.text:00401111                 mov     ebp, esp
.text:00401113                 mov     ecx, 7          ; ecx = 7
.text:00401118                 sub     esp, 1Ch
.text:0040111B                 cmp     [ebp+len_copy_hardcoded], ecx ; If strlen(copy_hardcoded) < ecx
.text:0040111E                 jle     exit_sub        ; then exit_sub()
.text:00401124                 mov     edx, [eax+8]
.text:00401127                 lea     edx, [ebp+edx+var_1C]
.text:0040112B                 mov     [ebp+var_4], edx ; v0 = mapping[8]
.text:0040112E                 mov     edx, [eax+0Ch]
.text:00401131                 lea     edx, [ebp+edx+var_1C]
.text:00401135                 mov     [ebp+var_8], edx ; v1 = mapping[12]
.text:00401138                 mov     edx, [eax+10h]
.text:0040113B                 lea     edx, [ebp+edx+var_1C]
.text:0040113F                 push    ebx
.text:00401140                 push    esi
.text:00401141                 mov     esi, [eax]
.text:00401143                 mov     [ebp+var_C], edx ; v2 = mapping[16]
.text:00401146                 mov     edx, [eax+14h]
.text:00401149                 push    edi
.text:0040114A                 mov     edi, [eax+4]
.text:0040114D                 mov     eax, [eax+18h]
.text:00401150                 lea     edx, [ebp+edx+var_1C]
.text:00401154                 mov     [ebp+var_10], edx ; v3 = mapping[20]
.text:00401157                 lea     edx, [ebp+eax+var_1C]
.text:0040115B                 mov     eax, offset copy_hardcoded ; j = 2
.text:00401160                 lea     esi, [ebp+esi+var_1C] ; v5 = mapping[0]
.text:00401164                 lea     edi, [ebp+edi+var_1C] ; v6 = mapping[4]
.text:00401168                 mov     [ebp+var_14], edx ; v4 = mapping[24]
.text:0040116B                 sub     ecx, eax        ; ecx -= eax
.text:0040116D                 lea     ecx, [ecx+0]    ; ecx = &ecx
.text:00401170
.text:00401170 top_Loop:                               ; CODE XREF: sub_401110+B6j
.text:00401170                 movzx   edx, byte ptr [eax-2]
.text:00401174                 mov     ebx, [ebp+var_4]
.text:00401177                 mov     [esi], dl       ; temp_arr[v5] = copy_hardcoded[j-2]
.text:00401179                 movzx   edx, byte ptr [eax-1]
.text:0040117D                 mov     [edi], dl       ; temp_arr[v6] =copy_hardcoded[j-1]
.text:0040117F                 movzx   edx, byte ptr [eax]
.text:00401182                 mov     [ebx], dl       ; temp_arr[v0] = copy_hardcoded[j]
.text:00401184                 movzx   edx, byte ptr [eax+1]
.text:00401188                 mov     ebx, [ebp+var_8]
.text:0040118B                 mov     [ebx], dl       ; temp_arr[v1] = copy_hardcoded[j+1]
.text:0040118D                 movzx   edx, byte ptr [eax+2]
.text:00401191                 mov     ebx, [ebp+var_C]
.text:00401194                 mov     [ebx], dl       ; temp_arr[v2] = copy_hardcoded[j+2]
.text:00401196                 movzx   edx, byte ptr [eax+3]
.text:0040119A                 mov     ebx, [ebp+var_10]
.text:0040119D                 mov     [ebx], dl       ; temp_arr[v3] = copy_hardcoded[j+3]
.text:0040119F                 movzx   edx, byte ptr [eax+4]
.text:004011A3                 mov     ebx, [ebp+var_14]
.text:004011A6                 mov     [ebx], dl       ; temp_arr[v4] = copy_hardcoded[j+4]
.text:004011A8                 mov     edx, [ebp+var_1C]
.text:004011AB                 mov     [eax-2], edx
.text:004011AE                 mov     dx, [ebp+var_18]
.text:004011B2                 mov     [eax+2], dx
.text:004011B6                 movzx   edx, [ebp+var_16]
.text:004011BA                 mov     [eax+4], dl
.text:004011BD                 add     eax, 7          ; j += 7
.text:004011C0                 lea     edx, [ecx+eax]  ; edx = ecx + 7
.text:004011C3                 cmp     edx, [ebp+len_copy_hardcoded] ; If edx < strlen(copy_hardcoded)
.text:004011C6                 jl      short top_Loop  ; then continue Loop
.text:004011C8                 pop     edi
.text:004011C9                 pop     esi
.text:004011CA                 pop     ebx
.text:004011CB
.text:004011CB exit_sub:                               ; CODE XREF: sub_401110+Ej
.text:004011CB                 mov     esp, ebp
.text:004011CD                 pop     ebp
.text:004011CE                 retn    4
.text:004011CE sub_401110      endp
.text:004011CE ; ---------------------------------------------------------------------------

Toàn bộ đoạn code trên thực hiện việc hoán đổi kí tự trong chuỗi byte_403140 (copy_hardcoded_str) dựa trên mảng mapping[] đã được tạo ra bởi sub_401000 đã phân tích trước đó. Mỗi lần thực hiện sẽ xử lý 7 kí tự của chuỗi byte_403140. Mã giả của đoạn code này được viết lại như sau:

FUNCTION sub_401110(mapping)
{
	int i=0, j = 2, ecx = 7, edx=0, k=0
	//create index for temp_arr[]
	v0 = mapping[8]
	v1 = mapping[12]
	v2 = mapping[16]
	v3 = mapping[20]
	v5 = mapping[0]
	v6 = mapping[4]
	v4 = mapping[24]
	do
	{
		temp_arr[v5] = copy_hardcoded[j-2]
		temp_arr[v6] = copy_hardcoded[j-1]
		temp_arr[v0] = copy_hardcoded[j]
		temp_arr[v1] = copy_hardcoded[j+1]
		temp_arr[v2] = copy_hardcoded[j+2]
		temp_arr[v3] = copy_hardcoded[j+3]
		temp_arr[v4] = copy_hardcoded[j+4]
		for (i=0; i&lt;=6; i++)
		{
			copy_hardcoded[k+i] = temp_arr[i];
		}
		j+=7
		edx = edx + ecx
		k = k+i
	}while (edx &lt;= strlen(copy_hardcoded))
	return copy_hardcoded	//after permute
}

Tổng kết lại, sub_401110 thực hiện phép hoán đối vị trí của kí tự tại byte_403140. Nó xây dựng index cho mảng temp_array[] dựa trên mảng mapping[] đã được tạo bởi sub_401000 và thực hiện hoán đổi từng khối 7 kí tự.

6. Phân tích sub_4011E0 – lần 3

Sau khi thực hiện xong sub_401110 ta sẽ quay trở về sub_4011E0, ta có đoạn code sau:

.text:00401243                 mov     ecx, edi        ; ecx = edi = szSerial
.text:00401245                 lea     eax, [ebp+var_1C] ; eax = &mapping[]
.text:00401248                 call    sub_401090

Ta thấy sẽ sub_401090 xử lý trên hai tham số truyền vào : [ebp+var_1C] như đã biết chứa thông tin về mảng mapping[], còn thanh ghi ecx edi lưu thông tin về szSerial mà ta nhập vào. Mã giả của đoạn code trên như sau:

sub_401090(mapping, serial)

7. Phân tích sub_401090

Toàn bộ code của sub như dưới đây:

.text:00401090 ; =============== S U B R O U T I N E =======================================
.text:00401090 sub_401090      proc near               ; CODE XREF: sub_4011E0+68p
.text:00401090                 movsx   edx, byte ptr [ecx] ; edx = szSerial[i]
.text:00401093                 add     edx, 0FFFFFFD0h ; edx = edx - 30h
.text:00401096                 push    esi             ; save esi
.text:00401097                 xor     esi, esi        ; esi = 0
.text:00401099                 mov     [eax], edx      ; mapping[0] = edx
.text:0040109B                 cmp     edx, 7          ; if edx >= 7
.text:0040109E                 jb      short loc_4010A2
.text:004010A0                 mov     [eax], esi      ; then mapping[0] = esi
.text:004010A2
.text:004010A2 loc_4010A2:                             ; CODE XREF: sub_401090+Ej
.text:004010A2                 movsx   edx, byte ptr [ecx+1] ; else edx = szSerial[i+1]
.text:004010A6                 add     edx, 0FFFFFFD0h ; edx = edx - 30h
.text:004010A9                 mov     [eax+4], edx    ; mapping[4] = edx
.text:004010AC                 cmp     edx, 7          ; if edx >= 7
.text:004010AF                 jb      short loc_4010B4
.text:004010B1                 mov     [eax+4], esi    ; then mapping[4] = esi
.text:004010B4
.text:004010B4 loc_4010B4:                             ; CODE XREF: sub_401090+1Fj
.text:004010B4                 movsx   edx, byte ptr [ecx+2] ; else edx = szSerial[i+2]
.text:004010B8                 add     edx, 0FFFFFFD0h ; edx = edx - 30h
.text:004010BB                 mov     [eax+8], edx    ; mapping[8] = edx
.text:004010BE                 cmp     edx, 7          ; if edx >= 7
.text:004010C1                 jb      short loc_4010C6
.text:004010C3                 mov     [eax+8], esi    ; then mapping[8] = esi
.text:004010C6
.text:004010C6 loc_4010C6:                             ; CODE XREF: sub_401090+31j
.text:004010C6                 movsx   edx, byte ptr [ecx+3] ; else edx = szSerial[i+3]
.text:004010CA                 add     edx, 0FFFFFFD0h ; edx = edx - 30h
.text:004010CD                 mov     [eax+0Ch], edx  ; mapping[12] = edx
.text:004010D0                 cmp     edx, 7          ; if edx >= 7
.text:004010D3                 jb      short loc_4010D8
.text:004010D5                 mov     [eax+0Ch], esi  ; then mapping[12] = esi
.text:004010D8
.text:004010D8 loc_4010D8:                             ; CODE XREF: sub_401090+43j
.text:004010D8                 movsx   edx, byte ptr [ecx+4] ; else edx = szSerial[i+4]
.text:004010DC                 add     edx, 0FFFFFFD0h ; edx = edx - 30h
.text:004010DF                 mov     [eax+10h], edx  ; mapping[16] = edx
.text:004010E2                 cmp     edx, 7          ; if edx >= 7
.text:004010E5                 jb      short loc_4010EA
.text:004010E7                 mov     [eax+10h], esi  ; then mapping[16] = esi
.text:004010EA
.text:004010EA loc_4010EA:                             ; CODE XREF: sub_401090+55j
.text:004010EA                 movsx   edx, byte ptr [ecx+5] ; else edx = szSerial[i+5]
.text:004010EE                 add     edx, 0FFFFFFD0h ; edx = edx - 30h
.text:004010F1                 mov     [eax+14h], edx  ; mapping[20] = edx
.text:004010F4                 cmp     edx, 7          ; if edx >= 7
.text:004010F7                 jb      short loc_4010FC
.text:004010F9                 mov     [eax+14h], esi  ; then mapping[20] = esi
.text:004010FC
.text:004010FC loc_4010FC:                             ; CODE XREF: sub_401090+67j
.text:004010FC                 movsx   ecx, byte ptr [ecx+6] ; esle ecx = szSerial[i+6]
.text:00401100                 add     ecx, 0FFFFFFD0h ; ecx = ecx - 30h
.text:00401103                 mov     [eax+18h], ecx  ; mapping[24] = ecx
.text:00401106                 cmp     ecx, 7          ; if ecx >= 7
.text:00401109                 jb      short loc_40110E
.text:0040110B                 mov     [eax+18h], esi  ; then mapping[24] = esi
.text:0040110E
.text:0040110E loc_40110E:                             ; CODE XREF: sub_401090+79j
.text:0040110E                 pop     esi             ; restore esi
.text:0040110F                 retn
.text:0040110F sub_401090      endp
.text:00401110 ; =============== S U B R O U T I N E =======================================

Nhìn thì thấy code khá dài, nhưng thuật toán của nó khá đơn giản. Mục đích cuối cùng là xây dựng lại mảng mapping[] dựa trên Serial đã nhập vào. Chuỗi Serial nhập vào bao gồm 7 chữ cái, được chuyển đổi thành 7 số nguyên và được lưu vào mảng mapping[] (nếu số đó nhỏ hơn 7) Mã giả của sub_401090 như sau:

FUNCTION sub_401090(mapping, serial)
    FOR i = 0 TO 6 DO
        temp = serial[i] - '0'
        IF nr >= 7 THEN
            mapping[i] = 0
        ELSE
            mapping[i] = temp
        ENDIF
    ENDFOR
END

8. Phân tích sub_4011E0 – lần 4

Sau khi sub_401090 nạp xong serial vào mảng mapping[], trở về sub_4011E0 và thấy lại tiếp tục có lời gọi tới sub_401110 để thực hiện hoán đổi kí tự một lần nữa:

.text:0040124D                 push    esi             ; len_copy_hardcoded
.text:0040124E                 lea     eax, [ebp+var_1C] ; eax = &mapping
.text:00401251                 call    sub_401110

sub_4011E0 kết thúc bằng một đoạn code thực hiện tính toán hash cho chuỗi byte_403140 (copy_hardcoded_str). Nếu như hash sau khi tính toán có giá trị tại eax là 0B45D7873h thì sẽ nhận được thông báo “Success”.

.text:00401256                 or      eax, 0FFFFFFFFh ; eax = 0xFFFFFFFF
.text:00401259                 mov     ecx, esi        ; ecx = strlen(copy_hardcoded_str)
.text:0040125B                 mov     edx, offset copy_hardcoded_str
.text:00401260                 test    esi, esi
.text:00401262                 jz      short loc_40127D
.text:00401264
.text:00401264 create_Hash:                            ; CODE XREF: sub_4011E0+9Bj
.text:00401264                 movzx   esi, byte ptr [edx] ; esi = copy_hardcoded_str[i]
.text:00401267                 xor     esi, eax        ; esi = esi ^ eax
.text:00401269                 and     esi, 0FFh       ; esi = esi & 0xFF
.text:0040126F                 shr     eax, 8          ; eax = eax / 100h (100h = 256)
.text:00401272                 xor     eax, ds:dword_402058[esi*4] ; eax = eax ^ (esi*4+402058)
.text:00401279                 inc     edx             ; i++ (next char of copy_hardcoded_str)
.text:0040127A                 dec     ecx             ; ecx--
.text:0040127B                 jnz     short create_Hash ; Loop until ecx = 0
.text:0040127D
.text:0040127D loc_40127D:                             ; CODE XREF: sub_4011E0+82j
.text:0040127D                 not     eax             ; eax = ~eax
.text:0040127F                 pop     esi
.text:00401280                 cmp     eax, 0B45D7873h ; If eax = 0xB45D7873h
.text:00401285                 jnz     short return_al_0
.text:00401287                 mov     eax, [ebp+arg_4]
.text:0040128A                 mov     dword ptr [eax], offset copy_hardcoded_str
.text:00401290                 mov     al, 1           ; then set al = 1
.text:00401292                 mov     esp, ebp
.text:00401294                 pop     ebp
.text:00401295                 retn
.text:00401296 ; ---------------------------------------------------------------------------
.text:00401296 return_al_0:                            ; CODE XREF: sub_4011E0+Aj
.text:00401296                                         ; sub_4011E0+1Aj ...
.text:00401296                 xor     al, al          ; else set al = 0
.text:00401298                 mov     esp, ebp
.text:0040129A                 pop     ebp
.text:0040129B                 retn
.text:0040129B sub_4011E0      endp
.text:0040129B ; ---------------------------------------------------------------------------

Mã giả của đoạn code trên như sau:

cal_hash = cal_hash_routine(message)
IF cal_hash = '0B45D7873h' THEN
    RETURN 1 // success
ELSE
    RETURN 0 // failure
ENDIF

9. Pseudo-Code

Tổng kết lại toàn bộ quá trình phân tích trên ta có được mã giả tương đối tường minh như sau:

FUNCTION name_mapping(szName)
    mapping = {0,1,2,3,4,5,6} // in eax = &var_1C
    FOR character IN szName DO
        IF character % 2 != 0 DO
            swap(mapping[0], mapping[1])
        ENDIF
        circular_left_shift(mapping)
    ENDFOR
    RETURN mapping
END

FUNCTION serial_mapping(szSerial)
    FOR i = 0 TO 6 DO
        temp = serial[i] - '0'
        IF nr >= 7 THEN
            mapping[i] = 0
        ELSE
            mapping[i] = temp
        ENDIF
    ENDFOR
    RETURN mapping
END

FUNCTION permutation(mapping)
{
	int i=0, j = 2, ecx = 7, edx=0, k=0
	//create index for temp_arr[]
	v0 = mapping[2]
	v1 = mapping[3]
	v2 = mapping[4]
	v3 = mapping[5]
	v5 = mapping[0]
	v6 = mapping[1]
	v4 = mapping[6]
	do
	{
		temp_arr[v5] = copy_hardcoded[j-2]
		temp_arr[v6] = copy_hardcoded[j-1]
		temp_arr[v0] = copy_hardcoded[j]
		temp_arr[v1] = copy_hardcoded[j+1]
		temp_arr[v2] = copy_hardcoded[j+2]
		temp_arr[v3] = copy_hardcoded[j+3]
		temp_arr[v4] = copy_hardcoded[j+4]
		for (i=0; i<=6; i++)
		{
			copy_hardcoded[k+i] = temp_arr[i];
		}
		j+=7
		edx = edx + ecx
		k = k+i
	}while (edx <= strlen(copy_hardcoded))
	return copy_hardcoded	//after permute
}

FUNCTION CHECK_SERIAL(szSerial, szName)
    IF strlen(serial) != 7 THEN
        RETURN 0
    END
    mapping = name_mapping(szName)

    STRCPY(copy_hardcoded_str, hard_coded_str) // clone hard coded message
    IF copy_hardcoded_str == NULL THEN
        GOTO loc_40123A \\ should never happen
    ENDIF
    copy_hardcoded_str = permutation(mapping)
    mapping = serial_mapping(szSerial)
    copy_hardcoded_str = permutation(mapping)
    cal_hash = cal_hash_routine(copy_hardcoded_str)
    IF cal_hash = '0B45D7873h' THEN
        RETURN 1 // success
    ELSE
        RETURN 0 // failure
    ENDIF
END

CHECK_SERIAL(szSerial, szName)

10. Tìm Key

Qua quá trình phân tích ở trên, ta đã nắm được cơ chế hoạt động của thuật toán. Việc tiếp theo là cần phải tìm ra quá trình hoán đối vị trí (permutation) sẽ tạo ra thông điệp plaintext (bản rõ) như thế nào. Ta có thông tin về thông điệp được mã hóa lưu tại byte_403010 là:

prncyI haorptge ,apy iamttru onbxo bPo -(r ix so)ot ehami  fbdofu-hftss igulnpodt e  trueemnrrtao beps sorat cisbSs -osn xsioer,us ptnntiieauf ifgdh inwsoatl rienssoinpg.

Để giải mã, chỉ cần tìm ra phép hoán vị cho một khối 7 kí tự. 7 chữ cái đầu tiên của bản mã là (bao gồm cả dấu cách):

prncyI

Nhìn vào 7 chữ cái này, ta có thể đoán chữ hoa “I” phải là kí tự đầu tiên, phần còn lại không quá khó để đoán, ta có được:

In cryp

Từ thông tin này ta suy luận ra được mảng mapping[] chuẩn phục vụ cho việc giải mã như sau:19

Như trên hình, chữ cái đầu tiên sẽ nằm ở vị trí thứ 6, chữ cái thứ hai nằm ở vị trí thứ 4, v..v… Từ đó, ta có bản đồ giải mã đúng là: 6 4 1 3 5 0 2

11. Viết Keygen sinh Serial theo Name nhập vào

Theo như quá trình phân tích ở trên, ta thấy crackme sử dụng hai lần phép hoán vị đối với bản mã (cipher text) để có được bản rõ (plain text). Lần đầu tiên thực hiện trên chuỗi Name, lần thứ hai thực hiện trên chuỗi Serial. Để viết được thuật toán sinh Serial cho chuỗi Name nhập vào, chúng ta cần phải tính toán kết quả mapping bằng việc thực hiện đoạn code name_mapping. Sau đó, ta có thể xác định mapping thứ hai sau khi kết hợp name mapping với kết quả mapping chính xác là 6 4 1 3 5 0 2.

Keygen code bằng C:

#include <stdio.h>
#include <string.h>

int main()
{
    char szName[20];
    char szSerial[8]="";
    int correct_key[] = {6, 4, 1, 3, 5, 0, 2};
    int mapping[] = {0, 1, 2, 3, 4, 5, 6};
    int i, temp=0;

    printf("Please enter your name: ");
    scanf("%s", szName);
    for (i=0; i&amp;lt;strlen(szName); i++)
    {
        if (szName[i] % 2 != 0)
        {
            temp = mapping[0];
            mapping[0] = mapping[1];
            mapping[1] = temp;
        }
        temp = mapping[0];
        mapping[0] = mapping[1];
        mapping[1] = mapping[2];
        mapping[2] = mapping[3];
        mapping[3] = mapping[4];
        mapping[4] = mapping[5];
        mapping[5] = mapping[6];
        mapping[6] = temp;
    }
    for (i=0; i&amp;lt;7; i++)
    {
        szSerial[mapping[i]] = (correct_key[i] + 0x30);
    }
    printf("Serial : %s", szSerial);

    return 0;
}

Keygen code bằng Python:

import argparse
from collections import deque

parser = argparse.ArgumentParser(description="SomeCrypto~02 keygen")
parser.add_argument('name')
args = parser.parse_args()
name = args.name #get Name args

correct_key = [6, 4, 1, 3, 5, 0, 2]
cypher = deque(list(range(7)))

#create mapping array based on Name.
for c in name:
    if ord(c) % 2:
        cypher[0], cypher[1] = cypher[1], cypher[0]
    cypher.rotate(-1)

serial = 7*[None] #create serial array and set None

for c, k in zip(cypher, correct_key):
    serial[c] = k

print('Right serial: ' + ''.join(str(s) for s in serial))

Kiểm tra key:

Kết quả kiểm tra keygen có được như sau:

Toàn bộ bài viết đến đây là kết thúc. Happy Reversing!!

Best Regards,

m4n0w4r


This plug-in is released by my friend, Vic aka vic4key (http://viclab.biz/)
Latest version: 2.06

Change Log:

—– [ MENU ] —–
Show the toolbar in the title of OllyDbg window
Maximize OllyDbg window when staring
Maximize OllyDbg child windows when staring
Show address info in status bar
Use APIs menu in OllyDbg menu bar
Apply confirm exit for OllyDbg
Make the transparency for OllyDbg window
Debuggee Data
Delete UDD data of the current session
Delete all UDD data
Open UDD data list
Delete recent debuggee files
Data Converter
DLL Process Viewer
File Location Converter
PE Viewer
Thread Viewer
Lookup Error Code
Find events of C++ Builder / Delphi VCL GUI application
Advanced Map File Importer
Map File Importer
Open Label window
Open Comment window
Bypass Anti Debugging
Hide the PEB
Data Copier
VA Address
RVA Address
Offset Address
ANSI String
UNICODE String
Code Ripped
Breakpoint Manager
INT3 Delete all
INT3 Import
INT3 Export
HWBP Delete all
HWBP Import
HWBP Export
MBP Delete all
MBP Import
MBP Export
Follow Me
Follow in Disassembler at <address>
Follow in Dump at <address>
Copy <address> to clipboard
Check for update
Infomation

—–[ Version 2.06 ]—–

[+] DATE UPDATE -> 24/09/2015

[+] NEW FEATURES
1. Show address info in status bar
2. Use APIs menu in OllyDbg menu bar (easier to set INT3 Breakpoint)
3. Apply confirm exit for OllyDbg (just ask for quit while you’re debugging)
4. Debuggee Data
Delete UDD data of the current session
Open UDD data list
Delete recent debuggee files
5. Thread Viewer (full thread infomation with Debug Register)
6. Find events of C++ Builder / Delphi VCL GUI application (working well, no need run to find)
7. Advanced Map File Importer
Open Label window
Open Comment window
8. Data Converter
Python/Ruby
9. Data Copier
ANSI String
UNICODE String
10. Breakpoint Manager (with my breakpoint file format)
INT3 Delete all
INT3 Import
INT3 Export
HWBP Delete all
HWBP Import
HWBP Export
MBP Delete all
MBP Import
MBP Export
11. Follow Me
Follow in Disassembler at <address>
Follow in Dump at <address>
Copy <address> to clipboard
12. Check for update (Update my plug-in by this function from now. No update via forums, blog, …)

[+] BUG FIX:
1. Show the toolbar in the title of OllyDbg window (fix for Windows 10)
2. File Location Converter (sync with ImageBase on loaded image, not file on disk)
3. Advanced Map File Importer
Map File Importer (sync with ImageBase & multi-modules)
4. Data Copier
VA Address
RVA Address
Offset Address

—–[ Version 2.05 ]—–

[+] DATE UPDATE -> 13/10/2013

[+] NEW FEATURES
<None>

[+] BUG FIX:
1. Crash OllyDbg when not used the toolbar
2. Delete UDD data
3. DATA Converter

—–[ Version 2.04 ]—–

[+] DATE UPDATE -> 24/03/2013

[+] NEW FEATURES
1. Lookup Error Code
2. Bypass anti debugging
Hide the PEB
3. Address copier
Copy VA
Copy RVA
Copy Offset

[+] BUG FIX:
1. Show the toolbar
2. DATA Converter
3. File Location Converter
4. Finding the Point Events in Delphi executables
5. Map file importer
Import labels
Import comments

Some screen shots:

Screenshot (0)Screenshot (1)Download here:

https://drive.google.com/file/d/0BzonFc1Y-m59Y1hmS0lfQTRKN0k/view

Regards,

m4n0w4r


Xin nói luôn là script này là để vui và để tìm hiểu thêm về Python, chứ còn thằng IDM nó dư sức làm việc này lolz ^-^.

Nhiều khi gặp một site tương tự như (https://crypto.stanford.edu/cs155/syllabus.html),  có chứa rất nhiều link tới các file pdfs và ppts/pptx, muốn download toàn bộ các file về nhưng mà ngại phải nhấn vào từng link một … rồi chọn Save As… Một vài file còn được chứ tầm trên chục file là ngại rồi🙂 . Dưới đây là một python script, tôi vô tình thấy trên mạng (http://pastebin.com/nRVXgmqF), tôi và cậu em cùng phòng (Hiep-TH) đã chỉnh sửa code chút xíu để có thể download thêm (ppt & pptx) cũng như fix một vài bug nhỏ trong quá trình thực hiện script để download file.

#Greatz thanks to Man Wuzi for this script (http://pastebin.com/nRVXgmqF)
#A little bit modify by me & my bro (Hiep-TH)

import urlparse
import urllib2
import os
import sys

try:
    from bs4 import BeautifulSoup
except ImportError:
    print "[*] Please download and install Beautiful Soup first"
    sys.exit(0)

url = raw_input("[+] Enter the url: ")
download_path = raw_input("[+] Enter the download path in full: ")

try:
    #set headers to make it look legit for the url
    headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
       'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
       'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
       'Accept-Encoding': 'none',
       'Accept-Language': 'en-US,en;q=0.8',
       'Connection': 'keep-alive'}

    i = 0    #count downloaded file

    request = urllib2.Request(url, None, headers) #requests URL with fake header
    html = urllib2.urlopen(request) #open URL and return file-like for page object
    
    html_src = html.read() #get all source code of specific page
    html_src_edited = html_src.replace("--!>", "-->")        #repalce --!> to --> (ex: cseweb.ucsd.edu/classes/su15/cse140-a/syllabus.html)
    
    #soup = BeautifulSoup(html.read()) #to parse the website
    soup = BeautifulSoup(html_src_edited, 'html.parser')

    for tag in soup.findAll('a', href=True): #find <a> tags with href in it so you know it is for urls
        #so that if it doesn't contain the full url it can the url itself to it for the download
        tag['href'] = urlparse.urljoin(url, tag['href'])

        #this is pretty easy we are getting the extension (splitext) from the last name of the full url(basename)
        #the splitext splits it into the filename and the extension so the [1] is for the second part( the extension)
        ext = os.path.splitext(os.path.basename(tag['href']))[1]
        if ext == '.pdf' or ext == '.ppt' or ext == '.pptx':
            request = urllib2.Request(tag['href'], None, headers)
            try:
                current = urllib2.urlopen(request)
                f = open(download_path + "\\" +os.path.basename(tag['href']), "wb")
                f.write(current.read())
                f.close()
                i+=1
                print "\n[*] Downloaded: %s" %(os.path.basename(tag['href']))
            except:
                print "\n[*] Missing/Non-Existing link: %s" %(tag['href'])
                continue

    print "\n[*] Total downloaded %d files" %(i+1)
    raw_input("[+] Press any key to exit ...")

except KeyboardInterrupt:
    print "[*] Exiting..."
    sys.exit(1)

except urllib2.URLError as e:
    print "[*] Could not get information from server!!"
    sys.exit(2)

except:
    print "I don't know the problem but sorry!!"
    sys.exit(3)

[IDA Plugin] Snowman

Posted: September 19, 2015 in [IDA Plugin] Snowman
Tags:

Home site: http://derevenets.com

Snowman (tên cũ trước đây là SmartDec), là một plugin hoàn toàn miễn phí, cung cấp khả năng dịch ngược về mã nguồn gốc C/C++ tương tự như plugin nổi tiếng HexRays, hỗ trợ đa nền tảng như x86, AMD64, và ARM. Plugin này tích hợp hoàn toàn với giao diện của IDA, hỗ trợ cho phép dịch ngược một hàm được lựa chọn hoặc toàn bộ chương trình chỉ bằng một phím tắt (nói theo ngôn ngữ teen bây giờ là “dịch ngược trong vòng một nốt nhạc”😀 ) và dễ dàng chuyển đổi qua lại giữa mã disassembler và mã đã được dịch ngược.

Phiên bản mới nhất của Plugin là v0.0.8 (17 September 2015), hỗ trợ các phiên bản IDA 6.3-6.8:

  • x86: automatic choice between AMD64 and MSVC 64-bit calling conventions.
  • PE parser: added parsing of exports (thanks to Jeff Muizelaar).
  • ELF parser: fixed reading of section headers in big-endian executables (thanks to Markus Gothe for reporting).
  • Improved LikeC code simplification: support for the index operator, special treatment of expressions in the boolean context, simplification of mathematical identities.
  • Improved and corrected reconstruction of expressions.
  • Fixed an error in the structural analysis leading to assertion failure during code generation.
  • ASCII strings detection is now more pessimistic.
Để sử dụng, tải plugin tại đường dẫn sau: http://derevenets.com/files/snowman-plugin-v0.0.8-win-qt4.8.7z. Sau đó giải nén và copy vào thư mục plugins của IDA. Sau khi load chương trình vào IDA để phân tích, lựa chọn hàm cần dịch ngược và nhấn phím tắt của plugin là F3.
 SnowmanHình minh họa
PS: Hiện tại, nhóm tác giả của plugin đang nỗ lực để hoàn thiện plugin này nhằm tạo ra mã tốt hơn (tham vọng chắc là phải tương đương HexRays🙂 ), giao diện tiện lợi hơn và hỗ trợ thêm nhiều nền tảng khác nữa. Trong quá trình sử dụng nếu có vấn đề gì liên quan có thể góp ý tại đây: https://github.com/yegord/snowman
Regards,
m4n0w4r

pyedit

Tác giả : storm shadow (aka Techbliss Owner (http://techbliss.org))
Thông tin về trình editor có thể xem tại đây: https://github.com/techbliss/Python_editor

Theo như tác giả viết, tác giả cảm thấy chán ghét khi phải thực thi các python script theo cách cũ, do đó đã nảy ra ý tưởng và tự code một trình Python Editor dành riêng cho IDA. Trình soạn thảo này tương tự như trình soạn thảo mà IDA đã có nhưng nó đẹp hơntốt hơn🙂 (theo như quảng cáo :D)

Để cài đặt và sử dụng được trình soạn thảo này (nếu như đọc trên site thì thấy tác giả viết hơi rối rắm🙂 hoặc có thể là do tôi đọc hoài không hiểu :P) thực hiện các bước sau đây:

  1. Vào link sau https://drive.google.com/file/d/0B5KQmTKmJ3kQNl9UQlMzMDZLMFE/view?usp=sharing để tải PyQt4_withcorrect_runtime.zip. Trong file nén này bao gồm các requirement packages để phục vụ việc thực thi trình soạn thảo, bao gồm PyQt4Sip dành cho PyQt4.
  2. Sau khi download được PyQt4_withcorrect_runtime.zip, tiến hành bung nén toàn bộ vào thư mục: C:\Python27\Lib\site-packages. Sau khi bung sẽ có được C:\Python27\Lib\site-packages\PyQt4 và 3 file sip tại C:\Python27\Lib\site-packages\
  3. Tiếp theo tải Python Editor v2 tại đây https://github.com/techbliss/Python_editor
  4. File download về là Python_editor-master.zip. Tiến hành bung nén, sau đó copy toàn bộ thư mục Code editor và file Python_editor.py vào thư mục plugins của IDA.
  5. Quá trình cài đặt hoàn tất, load IDA lên sẽ nhận được thông tin sau tại Output Window:opwindow
  6. Để kích hoạt, chọn Menu Edits > Plugins > Python Editor. Lúc đó, trình soạn thảo sẽ được load vào menu File, tương tự như hình dưới đây:
    editfilemenu
  7. Nhấn phím tắt Alt + E để mở trình Python Editor:
    PythonEditor

Chúc các bạn thành công!

Regards,
m4n0w4r

OllyDumpEx Plugin

Posted: September 8, 2015 in Uncategorized
Tags:

Overview

This plugin is process memory dumper for OllyDbg and Immunity Debugger. Very simple overview:

OllyDumpEx = OllyDump + PE Dumper – obsoleted + useful features

Features

  • Various debuggers supported
  • Select to dump debugee exe, loaded dll or non-listed module
  • Search PE File from memory
  • Multiple Dump mode. Rebuild for typical PE dump, Binary for PE Carving
  • PE32+ supported (Search and Binary Dump mode only available on 32bit debugger)
  • Native 64bit process supported (IDA Pro, WinDbg and x64_dbg)
  • Dump any address space as section even if not in original section header
  • Add dummy section to keep PE format consistency
  • Fix RVA in DataDirectory to follow ImageBase change
  • Auto calculate many parameters (RawSize, RawOffset, VirtualOffset, …)

Recent Changes

– v1.50 / 2015-07-03

  • Add: Fuzzy Search mode (for corrupted MZ/PE Signature)
  • Add: Fix Corrupted PE Header option (Fill Hole option is merged)
  • Add: Dump result dialog for copy and paste
  • Improve: Search method optimization
  • Improve: Corrupted PE Header handling
  • Improve: Binary dump mode support some options
  • Bugfix: Rebased PE handling (rebuild dump mode)
  • Bugfix: Debuggee filename error on attached process (IDA)
  • Bugfix: Get EIP does not work in recent version (x64_dbg)

a

Download here:

http://low-priority.appspot.com/ollydumpex/OllyDumpEx.zip

Regards,


OllyDbg is able to use dbghelp.dll and symsrv.dll to show extended debug information, such as the module source code (if referenced by the debug information) or module symbols from a PDB file (which can be fetched from the Microsoft Symbol Server for system modules). The problem is that if you turn on this option, module loading becomes much slower. On the other hand, this information is very handy, so there’s a dilemma as of whether to turn it on.

The Symbols on Demand plugin provides the best of both worlds: it disables loading of this extended debug information by default, but allows to load it explicitly for any module, at any time. Using this approach, loading is still fast, but if you need to load extended debug information for a module, you can easily do that.

OllyDbg v1.10 and v2.01 are supported. For, OllyDbg v1.10, there’s additional functionality: you can set the symbols search path, which is set by default to SRV.\Symbolshttp://msdl.microsoft.com/download/symbols. You can also choose to retrieve undecorated symbol names. These options can be set in the INI file of OllyDbg, in the plugin’s section.

Link: http://rammichael.com/symbols-on-demand


Note này tổng hợp một số Colour và Highlighting schemes dành cho bản OllyDBG v2.

  1. Tác giả có nick Xylitol, chia sẻ trên diễn đàn kernelmode.info:
    [Colour schemes]
    Scheme name[]=Instructions-Status-Dump Xyl
    Foreground_1[
    ]=,,0,F0FBFF,,,,,,,,,,,,
    Foreground_2[]=,,,,,,,,,,,,,,,*
    Background_1[]=C0C0C0,C0C0C0,C0C0C0,,,,,,,808080,,,,,,*
    Background_2[]=,,,,,,,,,,,,,,,*
    Operands[]=0
    Modified commands[
    ]=0
    Scheme name[]=Registers-Stack Xyl
    Foreground_1[
    ]=C0C0C0,FFFF,,,,,,,,,,,,,,
    Foreground_2[]=,,,,,,,,,,,,,,,*
    Background_1[]=,,,,,,,,,,,,,,,*
    Background_2[]=,,,,,,,,,,,,,,,*
    Operands[]=0
    Modified commands[
    ]=0
    [Highlighting schemes]
    Scheme name[]=Code Highlight Xyl
    Foreground_1[
    ]=,,,,,,,,,,,,800000,0,,
    Foreground_2[]=0,0,0,,800000,FF,,,,,,800000,800000,,8080,*
    Background_1[]=,,,,,,,,,,,,,,,*
    Background_2[]=FFFF00,FF00,,FF,,FFFFFF,,,,,,C0C0C0,C0C0C0,,C0C0C0,
    Operands[]=0
    Modified commands[
    ]=1

Preview:
Xylitol colour and highlighting scheme for olly v2

  1. Của một thành viên chia sẻ trên http://habrahabr.ru:
    [Colour schemes]
    Scheme name[6]=Blackboard
    Foreground_1[6]=F0F0F0,F0FBFF,AFAFAF,404FF,F0FBFF,F0FBFF,F0FBFF,F0FBFF,FFFFFF,F0FBFF,,,,,,
    Foreground_2[6]=,,,,,,,,,,,,,,,
    Background_1[6]=21100C,21100C,21100C,21100C,3939FF,C57941,EB9CAE,C57941,21100C,43322D,,,,,,
    Background_2[6]=,,,,,,,,,,,,,,,
    Operands[6]=0
    Modified commands[6]=0
    [Highlighting schemes]
    Scheme name[6]=Blackboard
    Foreground_1[6]=,,,,,,,,,,,,FFF,3939FF,3939FF,FFFF
    Foreground_2[6]=3939FF,3939FF,,,,,,,C57941,C57941,,8BE0AB,30B261,8BE0AB,30B261,
    Background_1[6]=,,,,,,,,,,,,,,,
    Background_2[6]=,,,3939FF,,,,,,,,,,,,*
    Operands[6]=1
    Modified commands[6]=1

Preview:

  1. Của tôi thiết lập theo Alex’s scheme dành cho bản OllyDBG v1:
    [Colour schemes]
    Scheme name[6]=m4n0w4r
    Foreground_1[6]=FF00,FFFF,FF00,0,F0FBFF,FF00FF,F0FBFF,F0FBFF,FFFFFF,FF00,,,,,,
    Foreground_2[6]=,,,,,,,,,,,,,,,
    Background_1[6]=0,0,0,FF,3939FF,C57941,EB9CAE,C57941,0,800080,,,,,,
    Background_2[6]=,,,,,,,,,,,,,,,
    Operands[6]=0
    Modified commands[6]=0
    [Highlighting schemes]
    Scheme name[6]=m4n0w4r
    Foreground_1[6]=,,,,,,,,,,,,FF00,FFFF,FF,FF00
    Foreground_2[6]=FF00FF,FF,FFFF00,0,8000,FFFF,,,C0DCC0,0,0,FF00,FFFF,FF,FFFF,*
    Background_1[6]=,,,,,,,,,,,,,,,
    Background_2[6]=,,,FFFFFF,,FF,,,,,,,,,,
    Operands[6]=0
    Modified commands[6]=1

Preview:
m4n0w4r_schemes

  1. Thiết lập của Vic4key:

vic4key light scheme
[Colour schemes]
Scheme name[7]=vic4key light
Foreground_1[7]=0,FF0000,808080,,0,,C0C0C0,FFFF,FFFFFF,0,,,,,,
Foreground_2[7]=,,,,,,,,,,,,,,,
Background_1[7]=FFFFFF,FFFFFF,FFFFFF,C0C0C0,,FF,808080,,FFFFFF,C0C0C0,,,,,,
Background_2[7]=,,,,,,,,,,,,,,,
Operands[7]=0
Modified commands[7]=0
[Highlighting schemes]
Scheme name[7]=vic4key light
Foreground_1[7]=,,,,,,,,,,,,,FF,FF,FF00FF
Foreground_2[7]=FFFF,FF,800000,FF,0,
,,,0,800000,808080,0,FF0000,8000,FF,*
Background_1[7]=,,,,,,,,,,,,,FFFF,FFFF,
Background_2[7]=FF,,,,,FF,,,,,,,,,FF00,*
Operands[7]=1
Modified commands[7]=1

Preview
VicLight

vic4key dark scheme
[Colour schemes]
Scheme name[6]=vic4key dark
Foreground_1[6]=FF00,FF00,FFFF00,0,,8000,,,FF00,,,,,,,
Foreground_2[6]=,,,,,,,,,,,,,,,
Background_1[6]=0,0,0,FF00,,0,808080,,FF,800000,,,,,,
Background_2[6]=,,,,,,,,,,,,,,,
Operands[6]=0
Modified commands[6]=0
[Highlighting schemes]
Scheme name[6]=vic4key dark
Foreground_1[6]=,,,,,,,,,,,,FFFF00,FFFF,FFFF,FF00FF
Foreground_2[6]=FFFF,FF,FFFF00,FF,FF,FF,,,FFFFFF,800000,808080,FFFF00,FFFFFF,FFFF,FF,*
Background_1[6]=,,,,,,,,,,,,,,,
Background_2[6]=,,,,,FFFF,,,,,,,,,,*
Operands[6]=1
Modified commands[6]=1

Preview:
VicDark

  1. Của KuNgBiM share trên các diễn đàn UnPackcN, PediY…

    [Colour schemes]
    Scheme name[4]=KuNgBiM's Scheme
    Foreground_1[4]=,,808000,0,FFFF,80,,FF00,,FF0000,,,,,,
    Foreground_2[4]=,,,,,,,,,,,,,,,
    Background_1[4]=C0DCC0,C0DCC0,C0DCC0,FF00,,FFFF00,,,C0DCC0,FFFF,,,,,,*
    Background_2[4]=,,,,,,,,,,,,,,,
    Operands[4]=0
    Modified commands[4]=0
    [Highlighting schemes]
    Scheme name[4]=KuNgBiM's Code
    Foreground_1[4]=,,,,,,,,,,,,FF0000,FF,FF,FF0000
    Foreground_2[4]=0,0,0,FF00,FF,FF,,,800000,0,0,800080,FF00FF,80,FF00FF,*
    Background_1[4]=,,,,,,,,,,,,,FFFF,FFFF,
    Background_2[4]=FFFF00,FF00,,FF,,,,,,,,,,,,*
    Operands[4]=1
    Modified commands[4]=0

Preview:
KungBIM

Best Regards,
m4n0w4r


stringfindnet

Plugin được chia sẻ từ các bạn TQ:

1.可扫描所有字符串,包含中文
2.列表内搜索定位
3.编码转换
4.列表框中增加字符长度和十六进制编码
5.快捷键改为 Ctrl+Y(ALT不习惯)

Bin + Source:

https://tenlua.vn/download/0837e127e50f6a0e1e/stringfindnetbin

https://tenlua.vn/download/0837e127e50f6a0e19/stringfindnetsrc

Regards,

 

OllyDbg_tut27

Posted: May 19, 2015 in OllyDbg_tut27
Tags:

Lâu quá không viết lách gì, nhân tiện những ngày tháng nhàn cư vi bất thiện, ở nhà vợ nuôi, tôi lại lục lại bộ tutorial cũ ra viết tiếp cho nó mềm tay, trơn mồm🙂.

Trong phần trước, tôi đã cùng các bạn tìm hiểu tổng quan các bước cơ bản để thực hiện unpack một file, kèm theo đó là thực hành một số phương pháp/cách thức làm thế nào để tìm được OEP. Trong phần 27 này, tôi sẽ trình bày nội dung tiếp theo liên quan tới việc Dump file và Repair IATs.

OllyDBG_27

Download here:
https://tenlua.vn/download/0837e127e40b650e14/ollydbgtut27

Pass để giải nén như đã đề cập ở phần 26, đó chính là OEP mà các bạn tìm được ở UnPackMe_tElock0.98.exe

Regards,
m4n0w4r


Who Am I – Kein System ist sicher“, tên tiếng Anh “Who Am I – No System Is Safe“, một bộ phim của Đức nói về đề tài Hacker. Trên IMDB được đánh giá 7.5, được coi là một bước ngoặt của điện ảnh Đức về đề tài nhạy cảm: tội phạm mạng. Nội dung phim xoay quanh Benjamin và nhóm tin tặc CLAY (Clowns laughing at you“), những kẻ lập dị, muốn chứng tỏ mình để trở nên nổi tiếng như Anonymous, Lizardsec, hay cụ thể hơn là như MRX (một hacker được cả nhóm tôn vinh là thần tượng)
whoami

CLAY gồm các thành viên:

  1. Max: chuyên sử dụng kỹ thuật Social engineering (đúc kết cuối cùng của phim thì đây là kĩ thuật đỉnh cao của đỉnh cao🙂 )
  2. Stefan: một chuyên gia về phần mềm, có thể tìm lỗi của bất kỳ ứng dụng nào :v
  3. Paul : một chuyên gia về phần cứng, có thể chế được nhiều toys😀
  4. Benjamin: thành viên cuối cùng gia nhập nhóm và cũng là nhân vật trung tâm của câu chuyện. Hoàn cảnh gia đình phức tạp: Cha bỏ rơi, Mẹ bị rối loạn đa nhân cách, Bà bị bệnh alzheimer. Có khả năng xậm nhập, hiểu được machine language, gõ 10 ngón nhanh như điện ….

CLAY chỉ đơn giản muốn chứng tỏ khả năng của mình, chứng tỏ mình không phải loại script kiddie, và muốn chứng tỏ khả năng cho MRX, nhóm không muốn làm hại ai. Tuy nhiên, khi bước vào cuộc chơi, mọi thứ bị đảo lộn, nhóm dính vào vụ thanh toán lẫn nhau của nhóm Fr13nds, mà trong đó MRX là thành viên, những kẻ bán dữ liệu cho Mafia Nga….

kickass

MRX có 3 quy tắc:

  1. No System Is Safe.
  2. Aim for the Impossible.
  3. Enjoy the meat world as much as the net world…..

mrx


Hex-Rays Decompiler plugin for better code navigation in RE process of C++ applications or code reconstruction of modern malware as Stuxnet, Flame, Equation … :octocat:

Contributors: Alex Matrosov (@matrosov) and Eugene Rodionov (@rodionov)

HexRaysCodeXplorer – Hex-Rays Decompiler plugin for easier code navigation. Right-click context menu in the Pseudocode window shows CodeXplorer plugin commands:

Download here:

https://github.com/REhints/HexRaysCodeXplorer


Author: ax330d

Link: https://github.com/ax330d/hrdev

Sơ lược: Đây là một plugin được tác giả viết bằng ngôn ngữ Python. Mục đích của tác giả khi xây dựng Plugin này chỉ đơn giản là muốn làm cho mã giả được tạo ra bởi Hex-Rays Decompiler trông dễ nhìn hơn. HRDEV sẽ lấy output của plugin chuẩn (tạo bởi Hex-Rays), sau đó phân tích output đó thông qua Python Clang, thực hiện một vài thay đổi, và kết xuất ra code ra một tab mới.

Cài đặt:

clang

  • Tiền hành cài đặt thêm LLVM (http://llvm.org/releases/3.6.0/LLVM-3.6.0-win32.exe)
  • Tiến hành kiểm tra lệnh import clang.cindex với Python trên cmd và Python trong IDA. Nếu không thấy báo lỗi “ImportError: No module named clang.cindex” là thành công.

Sử dụng:

  • Chạy IDA, load một target bất kỳ và đợi IDA hoàn tất quá trình phân tích.
  • Load HRDEV bằng cách nhấn Alt + F7, chọn và load file main.py.
  • Chọn function cần thực hiện decompile và nhấn “ALT + ,”. Kết quả so sánh khi thực hiện bằng Hex-Rays và HRDEV như sau:

Hex-Rays output:
Hrays

HRDEV output:

hrdev

Best Regards,

m4n0w4r

ODBGScript 2.0.1

Posted: April 9, 2015 in Uncategorized
Tags:

Author: VieuxCrapaud

ODbgScript is a plugin for OllyDbg 2.xx , which is, in our opinion, the best application-mode debugger out there. One of the best features of this debugger is the plugin architecture which allows users to extend its functionality. ODbgScript is a plugin meant to let you automate OllyDbg by writing scripts in an assembly-like language. Many tasks involve a lot of repetitive work just to get to some point in the debugged application. By using my plugin you can write a script once and for all.

Link: https://tenlua.vn/download/0837e22ae10e6d0615/odbgscript-v2-0-1

An Introduction To x64_dbg

Posted: March 20, 2015 in Uncategorized
Tags:

Author: Chester Fritz

Description: Welcome to this short, introductory tutorial for using x64_dbg by Mr. Exodia. The goal of this tutorial is to teach you some of the fundamentals of the x64_dbg and show you how closely its features and flexibility resembles its close cousin Ollydbg.While x64_dbg is still in an alpha stage, its bugs are minor and few with only a crash happening under unlikely conditions.

Full article: http://reverseengineeringtips.blogspot.com/2015/01/an-introduction-to-x64dbg.html

Regards,

m4n0w4r

OllyCapstone

Posted: February 4, 2015 in Uncategorized
Tags:

This is a plugin for OllyDbg 1.10 to replace the old disasm engine by Capstone disassembly/disassembler framework.

Screenshot:

Intel Syntax

Installation:

1.Copy OllyCapstone.dll into plugin directory (specified under Options | Directories | Plugin directory) 
2.Restart OllyDbg

Download here:
https://github.com/quangnh89/OllyCapstone

Regards,

m4n0w4r

2014 in review

Posted: December 31, 2014 in Uncategorized
Tags:

Tổng kết Blog năm 2014:

Khởi tạo từ tháng 09/2008, từ đó đến nay cái Blog này vẫn sống …. lay lắt, dù có không ít cơ số lần bị report😀 vì lý do này nọ, lọ chai. Mục đích của Blog này cũng vô cùng đơn giản, nó xuất phát từ sở thích và đam mê bên lề của tôi về Cracking/Unpacking/Reversing/Security, bên ngoài công việc thuần túy hàng ngày phục vụ cơm, áo, gạo, tiền và vô vàn những thứ cám dỗ khác trong cuộc sống vốn đã quá xô bồ, bon chen và nhỏ nhen này.

Mục đích thứ hai của Blog này là để tôi chia sẻ kiến thức “lượm nhặt” được của mình theo đúng nghĩa không vụ lợi, cũng là nơi để tôi giao lưu và kết bạn với những anh em, bạn bè có cùng sở thích, hay còn gọi với cụm từ chung là “giang hồ mạng”😀, và đặc biệt hơn cả là đám anh em trong REA-TEAM.

Dự định năm 2015:

  • Hi vọng là không có đồng chí nào report với thằng WordPress để nó block cái Blog này vì tôi ngại tạo mới.
  • Cố gắng hoàn thành nốt bộ OllyDBG tutorial như đã hứa (nhiều bạn hay hỏi là sao lâu thế không thấy anh ra bài mới, cũng phải thú thật là nhiều lúc để viết bài, tôi phải lọ mọ tranh thủ đêm hôm khi vợ con ngủ say lolz😀. Mà đêm hôm thì nhanh buồn ngủ, nên có khi gõ được vài chữ là tôi đóng mọe máy :D)

Here’s an excerpt:

The concert hall at the Sydney Opera House holds 2,700 people. This blog was viewed about 31,000 times in 2014. If it were a concert at Sydney Opera House, it would take about 11 sold-out performances for that many people to see it.

Click here to see the complete report.

Hiew.v8.43.MERRY.CHRISTMAS-DVT

Posted: December 28, 2014 in Uncategorized
Tags:

Hiew.v8.43.DVTDownload here: https://tenlua.vn/download/0837e628e7096d061f/d1f67hi1

Regards,

m4n0w4r

Bức Tường – Men say

Posted: December 26, 2014 in Uncategorized
Tags: ,

Men say, nằm trong album mới nhất của ban nhạc Bức Tường có tên “Đất Việt”. Nghe một lần là thấy lâng lâng….

“Người từ miền xuôi lên
Thử làm bạn với núi cao
Liêu xiêu bên vách đá chân chưa quen vượt đèo
Nghỉ tạm bên suối vắng, vốc nước khoát cho quên mỏi mệt
Nao nao mùi hương rừng dẫn lối.

Dặn lời vực chênh vênh
Liều nhìn xuống dưới chân
Chơi vơi và nao nao nghe tim đập lạ lùng
Đường chỉ vài quăng dao cheo leo cũng sẽ quen dần thôi
Chợ chiều xế bóng đợi dưới núi

Có dáng ai xòe váy mới
Ô nước da sao trắng ngần
Níu chân khách miền xuôi
Quý người uống mềm môi
Nâng lên bát rượu ngô uống một hơi bắt tay làm bạn
Lâng lâng trên tầng mây nghe lời ca vút bay cùng tiếng sáo

Người từ miền xuôi lên
Để lòng nơi núi cao.
Ưng nhau lại lên chơi như ai đã ngỏ lời
Đường đèo vẫn chênh vênh cheo leo cũng sẽ quen dần thôi
Nao nao mùi hương rừng dẫn lối…”

[Tool] Py2Exe Binary Editor

Posted: December 20, 2014 in Uncategorized
Tags:

Author: Extreme Coders

Py2Exe Binary Editor is a tool to reverse engineer py2exe generated executables. It can dump as well as modify the embedded python dll, pythonscript and library.zip.

Py2Exe

Download here:

https://sourceforge.net/projects/p2ebe/

Regards,

SANS Cyber Aces Online Courses

Posted: December 18, 2014 in Uncategorized
Tags: ,

SANS Cyber Aces Online makes available, free and online, selected courses from the professional development curriculum offered by The SANS Institute, the global leader in cyber security training. SANS goal in making these courses available as open courseware is to help grow the talent pool and accelerate the rate at which skilled cyber professionals can enter the information security industry – filling mission critical jobs currently going unfilled.

The open courses are the same as those offered to information security professionals around the world and are focused on the fundamentals of cyber security.

The course covers the three foundation areas of information security.

  • Operating Systems
  • Networking
  • Systems Administration

Link: http://www.cyberaces.org/courses/

Regards

m4n0w4r


Built to find everything
! BUG Fix! Entry: Compiler: Microsoft Visual C++ (RTL: __crtGetStringTypeA) misdetected
! BUG Fix! Entry: Compiler: Microsoft Visual C++ (RTL: __crtLCMapStringA) misdetected
* ZLib better detect
* Borland Turbo C 1.0 better detect
* MinGW32 better detect
* PowerBasic CC 3.x better detect (EP)
* CheckSum Adler32() better detect (RFC 1950)
* Borland Delphi version better detect
* Borland Delphi DCU Hdr magics
* Borland C++ Builder better detect
* Microsoft Visual C++ x64 better detect
* NIST B571 better detect
* LZX better detect
* Tiny Primes array better detect
* Hash padding array detection method changed
* WinZip SFX better detect
+ GCC Algo group
+ MINGW Algo group
+ QT Algo group
+ ACSS Crypt * http://www.openssh.com
+ MinGW32 2.x..4.x DLL (EP) * http://gnuwin32.sourceforge.net
+ MinGW64 2.x..4.x DLL (EP) * http://mingw-w64.sourceforge.net
+ Qt strings detect (use QT Algo)
+ Aladdin HASP SRM
+ Rar 5.x Archive Signature
+ Confuser .NET Obfuscator (String)
+ LZXC2 Hdr marker
+ SnakeSoftware ExeBook * http://s-soft.org
+ Photodex Installer * http://www.photodex.com
+ Map: Bits in byte count lookup table
+ Map: Power 2 table
+ eLicense initial detect * http://www.elicense.com

Download here:
https://tenlua.vn/download/0837e62fe00f64001f/cc13a10

Regards,


 sontrang

Nhân sinh lý lẽ ai ơi,
Làm người cốt được thảnh thơi đủ rồi.
Ai ai cũng có thời thăng giáng,
Chẳng một ai chỉ xuống không lên.
Trong may có rủi kề bên,
Rủi kia cũng sẵn có hên ẩn tàng.
Giàu sang đâu hẳn giàu sang mãi,
Trời chói chang có lúc xế chiều.
Trăng kia sáng mãi bao giờ,
Tròn rồi lại khuyết đầy chờ khi vơi.
Đất thoai thoải đông nam một cõi,
Vòi vọi nghiêng tây bắc trời cao.
Dù cho thiên địa nhường bao,
Cũng chưa toàn vẹn làm sao con người.
Chớ nên cau mặt nhíu mày,
Cũng đừng tranh cãi để cầu hơn ai.
Mặt hoa da phấn hôm nay,
Già hơn bữa trước một ngày còn chi?
Xuân qua đông lại tới thì,
Từ xưa vẫn thế có gì khác đâu.
Dù cho khôn khéo sang giàu,
Nghèo hèn ngu độn cũng đều như nhau.
Cõi trần kẻ trước người sau,
Cuối cùng cũng đến cái cầu xuôi tay.
Hôm nay chỉ biết hôm nay,
Trăm năm thấm thoát đã hay một đời.
Mấy ai thọ được bảy mươi,
Thời gian như nước chảy xuôi qua cầu.

OllyDbg_tut26

Posted: November 30, 2014 in OllyDbg_tut26
Tags:

Trong phần trước, tôi đã cùng các bạn tìm hiểu một số kiến thức tổng quan về packer, về layout của PE file sau khi bị pack, tóm lược các bước cơ bản khi thực thi một chương trình bị pack, và quan trọng nhất là chúng ta đã hiểu rõ hơn thuật ngữ OEP – là nơi dòng lệnh đầu tiên của file gốc được thực thi. Thông thường, 99% là OEP sẽ nằm ở section đầu tiên (đó là section .text (code), bên dưới PE header khi quan sát trong cửa sổ Memory map của OllyDBG), tuy nhiên vẫn có những trường hợp ngoại lệ là OEP không nằm tại section đầu tiên. Nhưng về bản chất thì cuối cùng OEP vẫn phải nằm đâu đó thuộc Executable Code Section, có tên là .text (Micro$oft) hoặc là CODE (Borland). Trong phần 26 này tôi sẽ giới thiệu tới các bạn một số phương pháp cơ bản, phổ biến, thường áp dụng khi tìm OEP.

N0w let’s g0……smile

Download here: https://tenlua.vn/download/0837e02ce9096505/ollydbgtut26

Regards,

m4n0w4r


Author: athre0z

REtypedef is an IDA PRO plugin that allows definition of custom substitutions for function names. It comes with a default ruleset providing substitutions for many common STL types. If you ever reversed software that makes heavy use of STL classes, you can probably figure out why you would need such a plugin.

Without REtypedef:

.text:0040142E ; =============== S U B R O U T I N E =======================================
.text:0040142E
.text:0040142E ; Attributes: thunk
.text:0040142E
.text:0040142E public: void __thiscall std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>>::swap(class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>> &) proc near
.text:0040142E
.text:0040142E _Right          = dword ptr  4
.text:0040142E
.text:0040142E                 jmp     std::basic_string<char,std::char_traits<char>,std::allocator<char>>::swap(std::basic_string<char,std::char_traits<char>,std::allocator<char>> &)
.text:0040142E public: void __thiscall std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>>::swap(class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>> &) endp
.text:0040142E
.text:00401433
.text:00401433 ; =============== S U B R O U T I N E =======================================
.text:00401433
.text:00401433 ; Attributes: thunk
.text:00401433
.text:00401433 public: class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>> & __thiscall std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>>::insert(unsigned int, class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>> const &) proc near
.text:00401433
.text:00401433 _Off            = dword ptr  4
.text:00401433 _Right          = dword ptr  8
.text:00401433
.text:00401433                 jmp     std::basic_string<char,std::char_traits<char>,std::allocator<char>>::insert(uint,std::basic_string<char,std::char_traits<char>,std::allocator<char>> const &)
.text:00401433 public: class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>> & __thiscall std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>>::insert(unsigned int, class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>> const &) endp

With REtypedef:

.text:0040142E ; =============== S U B R O U T I N E =======================================
.text:0040142E
.text:0040142E ; Attributes: thunk
.text:0040142E
.text:0040142E public: void __thiscall std::string::swap(class std::string &) proc near
.text:0040142E
.text:0040142E _Right          = dword ptr  4
.text:0040142E
.text:0040142E                 jmp     std::string::swap(std::string &)
.text:0040142E public: void __thiscall std::string::swap(class std::string &) endp
.text:0040142E
.text:00401433
.text:00401433 ; =============== S U B R O U T I N E =======================================
.text:00401433
.text:00401433 ; Attributes: thunk
.text:00401433
.text:00401433 public: class std::string & __thiscall std::string::insert(unsigned int, class std::string const &) proc near
.text:00401433
.text:00401433 _Off            = dword ptr  4
.text:00401433 _Right          = dword ptr  8
.text:00401433
.text:00401433                 jmp     std::string::insert(uint,std::string const &)
.text:00401433 public: class std::string & __thiscall std::string::insert(unsigned int, class std::string const &) endp

Custom rules can be defined at “Options/Edit name substitutions…”.

Latest binary release (IDA 6.1 – 6.6 Windows): https://github.com/athre0z/REtypedef/releases/latest

Cao xứ bất thắng hàn

Posted: November 29, 2014 in Uncategorized

diepcothanh

“Trăng kia có tự bao giờ
Mà sao khi tỏ khi mờ trăng ơi
Nâng chén rượu lạt hỏi chơi
Thiên đình nơi ấy nay thời kỳ nao
Niên nhật ngày tháng năm nào?
Để tôi lướt gió bay vào cung trăng
Lầu son gác tía giăng giăng
Điện ngọc lạnh lẽo e rằng khó lên
Thôi thì đặt chén sang bên
Nhảy cùng với bóng cho quên chốn sầu

Trăng lên lấp lánh trên đầu
Xoay vòng một trục bắc cầu vào chơi
Thương nhau đã hết một đời
Thì không nên hận, nói lời đắng cay
Nhưng sao trăng xuống nơi này
Rồi tròn đúng lúc người say một mình
Buồn vui ly hợp sinh linh
Phải là quy luật một mình nhân gian?
Trăng cao cũng chẳng vẹn toàn
Khi tròn khi khuyết mơ màng hiển minh
Nguyện cho nhân thế hữu tình
Nhân thành quyến thuộc như bình rượu ngon
Trăng khuyết rồi lại trăng tròn
Nghìn dặm một ánh người còn thấy nhau.”

_ST_

[OllyDbg2] LabelArgs

Posted: November 14, 2014 in Uncategorized

Mr. eXoDia: port the LabelArgs plugin by High6 to OllyDbg2.

If you add a label like “setTls(int index, PVOID value)” to a function and analyse you will have more meaningful arguments (“int index” instead of “Arg1”).
Before:
labelargs_before

After:
labelargs_after

Download link:
https://bitbucket.org/mrexodia/labelargs/downloads

Regards,

ODG1.10_HardWareInfo Plugin

Posted: November 14, 2014 in Uncategorized

by ESSO_X
HW info

Download here:
https://tenlua.vn/download/0837e127e8036800/odg2hardwareinfov1-0-2-3at4re

Regards