ZeroAccess new variant (Self Debugging)Unpacker

ZeroAccess new variant (crypter) is in the news from past   few days. It is different from traditional crypters which either uses RunPE or overwrite  the   original image with decrypted Image.It is already covered in avast blog post ,so i  will just summarize it in shorter steps.It Basically uses Self debugging concept (it’s not a  new thing)

1)Launch its own  instance  in debug mode (child process)
2)Parents Process Enter into debug loop ,and  listen for events from debugee and handle them
3)It decrypts the Embedded PE when it Receives  SINGLE_STEP  Exception

After Decrypting the Image we have following  Function

.text:004013DA ZeroAccess_PE_Load proc near ; CODE XREF: sub_4014A7+42p
.text:004013DA Local_SizeofImage= dword ptr -14h
.text:004013DA var_10 = dword ptr -10h
.text:004013DA var_C = dword ptr -0Ch
.text:004013DA Section_Handle = dword ptr -8
.text:004013DA Section_Base_Address= dword ptr -4
.text:004013DA Decompress_Binary= dword ptr 8
.text:004013DA Size = dword ptr 0Ch
.text:004013DA push ebp
.text:004013DB mov ebp, esp
.text:004013DD sub esp, 14h
.text:004013E0 push ebx
.text:004013E1 push esi
.text:004013E2 push edi
.text:004013E3 push [ebp+Decompress_Binary]
.text:004013E6 call ds:RtlImageNtHeader
.text:004013EC mov ebx, eax
.text:004013EE xor esi, esi
.text:004013F0 cmp ebx, esi ; Check if Valid NT Header
.text:004013F2 jz Invalid_Nt_Header_Return_0
.text:004013F8 mov eax, [ebx+IMAGE_NT_HEADERS32.OptionalHeader.SizeOfImage]
.text:004013FB push esi
.text:004013FC mov [ebp+Local_SizeofImage], eax
.text:004013FF push SEC_COMMIT
.text:00401404 xor eax, eax
.text:00401406 push PAGE_EXECUTE_READWRITE
.text:00401408 lea edi, [ebp+var_10]
.text:0040140B stosd
.text:0040140C lea eax, [ebp+Local_SizeofImage]
.text:0040140F push eax
.text:00401410 push esi
.text:00401411 push SECTION_ALL_ACCESS
.text:00401416 lea eax, [ebp+Section_Handle]
.text:00401419 push eax
.text:0040141A call ds:ZwCreateSection
.text:00401420 test eax, eax
.text:00401422 jl short Invalid_Nt_Header_Return_0
.text:00401424 push 4
.text:00401426 push esi
.text:00401427 push 2
.text:00401429 lea eax, [ebp+var_C]
.text:0040142C push eax
.text:0040142D push esi
.text:0040142E push esi
.text:0040142F push esi
.text:00401430 lea eax, [ebp+Section_Base_Address]
.text:00401433 push eax
.text:00401434 push 0FFFFFFFFh
.text:00401436 push [ebp+Section_Handle]
.text:00401439 mov [ebp+Section_Base_Address], esi
.text:0040143C mov [ebp+var_C], esi
.text:0040143F call ds:ZwMapViewOfSection
.text:00401445 test eax, eax
.text:00401447 jl short Close_Handle
.text:00401449 mov edi, [ebp+Section_Base_Address]
.text:0040144C mov esi, [ebp+Decompress_Binary]
.text:0040144F mov ecx, [ebx+IMAGE_NT_HEADERS32.OptionalHeader.SizeOfHeaders]
.text:00401452 rep movsb
.text:00401454 movzx edx, [ebx+IMAGE_NT_HEADERS32.FileHeader.NumberOfSections]
.text:00401458 movzx eax, [ebx+IMAGE_NT_HEADERS32.FileHeader.SizeOfOptionalHeader]
.text:0040145C lea eax, [eax+ebx+IMAGE_NT_HEADERS32.OptionalHeader]
.text:00401460 test edx, edx
.text:00401462 jz short If_Zero_Section
.text:00401464 add eax, 14h ; PImage_Section_Header->PointertoRawData
.text:00401467 Copy_Sections: ; CODE XREF: ZeroAccess_PE_Load+A1j
.text:00401467 mov esi, [eax] ; ESI=Pointer to Raw Data
.text:00401469 mov edi, [eax-8] ; EDI=Virtual_Address
.text:0040146C add esi, [ebp+Decompress_Binary] ; PointerToRawData_Binary_ImageBase
.text:0040146F add edi, [ebp+Section_Base_Address]
.text:00401472 mov ecx, [eax-4] ; SizeOfRawData
.text:00401475 add eax, 28h ;Point to Next Section Headerr
.text:00401478 dec edx ;decrement no_of_section
.text:00401479 rep movsb
.text:0040147B jnz short Copy_Sections ; ESI=Pointer to Raw Data
.text:0040147D If_Zero_Section: ; CODE XREF: ZeroAccess_PE_Load+88j
.text:0040147D push [ebp+Section_Base_Address]
.text:00401480 push 0FFFFFFFFh
.text:00401482 call ds:ZwUnmapViewOfSection
.text:00401488 mov eax, [ebp+Section_Handle]
.text:0040148B mov ecx, [ebp+Size]
.text:0040148E mov [ecx], eax
.text:00401490 xor eax, eax
.text:00401492 inc eax
.text:00401493 jmp short Return
.text:00401495 ; ---------------------------------------------------------------------------
.text:00401495 Close_Handle: ; CODE XREF: ZeroAccess_PE_Load+6Dj
.text:00401495 push [ebp+Section_Handle]
.text:00401498 call ds:ZwClose
.text:0040149E Invalid_Nt_Header_Return_0: ; CODE XREF: ZeroAccess_PE_Load+18j
.text:0040149E ; ZeroAccess_PE_Load+48j
.text:0040149E xor eax, eax
.text:004014A0 Return: ; CODE XREF: ZeroAccess_PE_Load+B9j
.text:004014A0 pop edi
.text:004014A1 pop esi
.text:004014A2 pop ebx
.text:004014A3 leave
.text:004014A4 retn 8hg
.text:004014A4 ZeroAccess_PE_Load endp

This  routine act as a PE Loader ,it reads PE Header and Load PE Decrypted Image Accordingly

So where we can possibly dump it ??

A really good candidate is RtlImageNtHeader !!!

Prototype from ReactOs

PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(IN PVOID ModuleAddress );

It takes Raw Binary as Input and Give Back Pointer to IMAGE_NT_HEADERS,So idea is to Hook the RtlImageNtHeader and Dump the Memory Block,As we are dumping to binary in raw state so we do not have to realign the binary .

RtlImageNtHeader can be called by other windows dll internally  ,so to  get  the correct call  just check if it is  called
from  main executable (ImageBase  to ImageBase+SizeofImage) by checking return address.

ZeroAccess Unpacker Download Link

1)Inject.exe =>Start executable in suspended mode and Inject dll(using CreateRemoteThread),after sleeping for 400ms resume
main thread
2)ZeroAcccess_Unpack.dll=> dll that install hooks  and dump unpacked file

Note :This did not  include any check if sample is ZeroAccess,if you provide  non ZeroAccess sample it will produce
unexpected results

Usage :
inject.exe sample.exe

Malware Reversing Part 1

MD5 Hash  : 1d8ea40a41988b9c3db9eff5fce3abe5

This  is First Part of   2 Part Series .This Malware Drops A File (All  malwares do it usually)..So in This Part We will only Analyze Dropper and Next Part We will Analyze Dropped File.

Originally  Sample is  Downloaded  from ..It is very Good Place   for Malware Samples and Reverse Engineering .I  Uploaded the Sample to sendspace ..The Password to File is “infected”


Anyway Start With Basic Stuff..Check it  with ExeInfo/Protection ID for  Packer Detection or Compiler Detection .

NOTE: I  Have Dedicated Virtual Machine For Malware Analysis .I recommend You to have same..

Here are Results From ExeInfo/Protection ID

So  Sample is  Not Packed .:D (Normally Malwares Are packed )

Compiler Detected : Visual C++ 2008

Fine Till Now

Visual C++ Targets are Kind of Ideal For Reversing ..Unlike Delphi Targets That Contain annoying Calls..VC++ Targets are Relatively Easier to Reverse .

Debugger /Disassembler  we are going to use are



I  have a habit of Running Both IDA and Ollydbg  parallely .IDA is very Powerful Due to Its Features Like  Renaming  the Variables, Functions ,Locations and  Cross Reference etc ..Ollydbg is my Personal Favorite Debugger.

Also This Article is mainly to demonstrate Reverse Code Engineering ..I will try to Reverse Engineer Important parts of Malware .

Trace into Ollydbg Till WinMain  = 00401648 or Use IDA ..IDA By default Start From  WinMain

So lets start  Analyzing from WinMain

00401648  /$  8BFF           MOV EDI,EDI                              //Do Nthing

0040164A  |.  55               PUSH EBP                                   //Standard Function Start –Save  Frame Pointer

0040164B  |.  8BEC          MOV EBP,ESP                           //Move Stack Pointer to  EBP

0040164D  |.  83EC 1C     SUB ESP,1C                           //Allocate 1C (28) Bytes For Local Variables

00401650  |.  56               PUSH ESI                               //Save Registers Before Calling

00401651  |.  57               PUSH EDI                                

00401652  |.  E8 120D0000   CALL sample.00402369     

Lets Trace Into This Call.. Disassembly Inside Call Looks Like  This

Lets Start From Something Interesting.. We have  A   Call To API   “GetModuleHandleW” ,the argument passed  is 0 .

We All  Know  GetModuleHandleW(NULL)..Returns  Imagebase of Currently Loaded Executable  in EAX ..So  This Call returns the Imagebase of sample.exe ..Next few Lines are  Interesting

0040237A  |.  8BF0                        MOV ESI,EAX                                            //Now ESI Contain  Imagebase

0040237C  |.  8B46 3C                 MOV EAX,DWORD PTR DS:[ESI+3C]   //Get  NT HEADER OFFSET

0040237F  |.  8B9C30 800000   MOV EBX,DWORD PTR DS:[EAX+ESI+80]     //Image_import_Directory                

00402386  |.  03DE                      ADD EBX,ESI                            //Address Of _IMAGE_IMPORT_DESCRIPTOR Structure

00402388  |.  8B43 0C                MOV EAX,DWORD PTR DS:[EBX+C]   //Point to  Name Field of _IMAGE_IMPORT_DESCRIPTOR

To Understand Above Code ..You Need Some Basic Understanding  of PE Format …

First  Here We Have  = Imagebase+3c

In PE Format First We have   IMAGE_DOS_HEADER …..Lets Explore IMAGE_DOS_HEADER in  Windbg

Ignore Other Fields.. Here  we have e_lfanew at offset 0x3C.

e_lfanew Actually Contains  the offset to  PE Header


So above instruction is to get  NT Header Offset

Imagebase is added as we are parsing the File in Memory  ..Hope it is Clear Now


So What We have is  Load value at      Imagebase+NT_HEADER+0x80  into EBX ..

Each PE File Contains   Array of   IMAGE_DATA_ DIRECTORY Structures .Lets Look Into  IMAGE_DATA_DIRECTORY  Structure

So Each IMAGE_DATA_DIRECTORY Contains Two Fields   Virtual Address and Size

NT_HEADER+80 Points to  Import_table_address .. The Values of that Directory are

00400170    D4320000    DD 000032D4          ;  Import Table address = 32D4

00400174    78000000    DD 00000078          ;  Import Table size = 78 (120.)

I  Took these values from Memory Window  of  Ollydbg ..

So what above instruction doing is getting  the import table address  ..

*Import table is very important concept ..It basically contains the info about  imported functions/Dlls

Add Imagebase  with Import Table address  as we are parsing file in memory

ADD EBX,ESI                           

Next Instruction is


This is Interesting .. Import Table is actually a Array of  IMAGE_IMPORT_DESCRIPTOR.. Each  IMAGE_IMPORT_DESCRIPTOR Structure  Contains a Info about  Single DLL and Info about Functions imported from this DLL ..SO  NO. of  IMAGE_IMPORT_DESCRIPTOR= No. of DLLs


    DWORD Characteristics;
    DWORD OriginalFirstThunk;
  DWORD TimeDateStamp;
  DWORD ForwarderChain;
  DWORD Name;    //offet 0xc
  DWORD FirstThunk;  //offset 0x10

So in  Above Instruction ESI is Pointing to  Name  From IMAGE_IMPORT_DESCRIPTOR

0040238D  |.  8975 F8       MOV [LOCAL.2],ESI                        //Save  ESI  Into Local_var

So Next  is Loop ..We Can Easily See this in  our dear Ollydbg ..Lets Look Into Loop

00402397  |> /03C6          /ADD EAX,ESI                             //Get Name of DLL In Memory

00402399  |. |68 28134000   |PUSH sample.00401328                    ; /s2 = “user32.dll”   //Constant String

0040239E  |. |50            |PUSH EAX                                ; |s1 = 000036E4 ???                /

0040239F  |. |FF15 48114000 |CALL DWORD PTR DS:[<&msvcrt._stricmp>]  ; \_stricmp

004023A5  |. |85C0          |TEST EAX,EAX

004023A7  |. |59            |POP ECX                                 ;  sample.00404C78

004023A8  |. |59            |POP ECX                                 ;  sample.00404C78

004023A9  |. |0F85 A0000000 |JNZ sample.0040244F

So  what above instructions Doing are

1)Get   Address of DLL_NAME in Memory

2) Compare the DLL_NAME with “ user32.dll”

3) IF  DLL_NAME !=”user32.dll” then    Go to  NEXT  IMAGE_IMPORT_DESCRIPTOR   Structure

4)Go to Step 1

So this Loop Continues  Untill DLL NAME IS “user32.dll”

So lets Look What Happen  When  condition is True ..I mean DLL NAME == “user32.dll”

Jump AT 004023A9 is Conditional Jump ..That Not taken If  DLL Name ==”user32.dll”  .So lets Look Into Code  Below the conditional Jump   when we Got a Match with  DLL  Name .

004023AF  |.  8B3B          MOV EDI,DWORD PTR DS:[EBX]    //Get Address OF   RVA of IAT in EDI

004023B1  |.  03FE          ADD EDI,ESI                                       // Get In Memory Address

004023B3  |.  8B73 10       MOV ESI,DWORD PTR DS:[EBX+10]    // RVA of FirstThunk

004023B6  |.  0375 F8       ADD ESI,[LOCAL.2]                    //        IN Memory Address of FirstThunk

So what Above Code Does  is   Get IN Memory Address(Virtual Address of FirstThunk)..

(Look into PE format to Know More About IAT)

This Whole Procedure is Actually to   Parse the Names of APIs Imported By  DLL.

004023BE  |> /8B4D F8       MOV ECX,[LOCAL.2]                     

004023C1  |. |8D4408 02     LEA EAX,DWORD PTR DS:[EAX+ECX+2]    //Point To Name Of API

So finally Now it Point to Name of APIs Imported By User32.dll

004023BE  |> /8B4D F8            MOV ECX,[LOCAL.2]                      ;  sample.00400000

004023C1  |. |8D4408 02       LEA EAX,DWORD PTR DS:[EAX+ECX+2]

004023C5  |. |68 14134000    PUSH sample.00401314                   ; /s2 = “RegisterClassExW”

004023CA  |. |50                      PUSH EAX                               ; |s1 = “TranslateMessage”

004023CB  |. |FF15 48114000 CALL DWORD PTR DS:[<&msvcrt._stricmp>] ; \_stricmp

Check If Current  API Name == RegisterClassExW (here it is not equal as First  API Imported is Translate Message ).

004023D1  |. |85C0             TEST EAX,EAX                           ;  sample.004037D2

004023D3  |. |59                  POP ECX                                ;  sample.004037D2

004023D4  |. |59                  POP ECX                                ;  sample.004037D2

004023D5  |. |75 25            JNZ SHORT sample.004023FC

If   API  Name Matched then   DO not JUMP(Execute the Code Below)  If   Not Matched then JUMP

004023D7  |. |8D45 FC        LEA EAX,[LOCAL.1]

004023DA  |. |50                 PUSH EAX                            ; /pOldProtect = sample.004037D2

004023DB  |. |6A 40          PUSH 40                                ; |NewProtect = PAGE_EXECUTE_READWRITE

004023DD  |. |6A 04         PUSH 4                                 ; |Size = 4

004023DF  |. |56               PUSH ESI                               ; |Address = <&USER32.TranslateMessage>

004023E0  |. |FF15 44104000 CALL DWORD PTR DS:[<&KERNEL32.VirtualP>; \VirtualProtect

004023E6  |. |8D45 FC       LEA EAX,[LOCAL.1]




Size=  4

HERE SIZE = 4 Bytes as Probably  it  Going to Overwrite the API Address (  As we are on 32 bit Arcitecture so Address = 4bytes=32 bits)

Address =  ESI ( API ADDRESS)   (Address  of Target API)

004023E9  |. |50                  PUSH EAX                               ; /pOldProtect = sample.004037D2

004023EA  |. |C706 EF194000 MOV DWORD PTR DS:[ESI],sample.004019EF

OverWrite the  API Address    With  004019EF (Other Function Address)

004023F0  |. |FF75 FC         PUSH [LOCAL.1]                         ; |NewProtect = PAGE_READONLY|PAGE_WRITECOPY

004023F3  |. |6A 04            PUSH 4                                 ; |Size = 4

004023F5  |. |56                  PUSH ESI                               ; |Address = <&USER32.TranslateMessage>

004023F6  |. |FF15 44104000 CALL DWORD PTR DS:[<&KERNEL32.VirtualP>; \VirtualProtect

Restore the  Original Permission Using VirtualProtect

Same Is For  Next  Part Of LOOP  .. it checks API  Against “CreateWindowExW”.If Name Matched then  Use VirtualProtect to   Make that Memory portion Writable .Then Change Address and Again Restore Permission

So let me  Write A Pseudo Code To Describe what Just Happened  in This LOOP


If   stricmp(Image_Import_descriptor->Name,”user32.dll)  //Label2


        Parse  using  FirstThunk ..Get API NAMES..

       If stricmp(Current_API ,”RegisterClassExW”)        //Label1


           VirtualProtect(Address_of_API,Size(4Bytes), PAGE_EXECUTE_READWRITE,PoldProtec)

           //  Make it Writable

            Address_of_API= 004019EF

        VirtualProtect()   //Restore original Permissions


          Else if(Stricmp(Current API,”CreateWIndowExW”)


                VirtualProtect(Address_of_API,Size(4Bytes), PAGE_EXECUTE_READWRITE,PoldProtec)

               //  Make it Writable

                  Address_of_API= 00402228

             VirtualProtect()   //Restore orginal Permissions




           Get Next  API NAME 

               }     //Start From Label 1




//Start From Label 2   ..Once Two Functions are matched Loop Terminates

SO After End OF LOOP  We have



Finally Functions Ends and Return …So  main Motive is this Function to Make Some Modification in IAT

After  Call ..There are some  Calls  to Resources..More Likely   Fake Calls ..As Called Resource  does not Exist

00401657  |.  8B7D 08       MOV EDI,[ARG.1]                                   // Move ImageBase Into EDI

0040165A  |.  8B35 C8104000 MOV ESI,DWORD PTR DS:[<&USER32.LoadStringW>]      ;  USER32.LoadStringW

00401660  |.  6A 64         PUSH 64                                                                  ; /Count = 64 (100.)

00401662  |.  68 C04A4000   PUSH sample.00404AC0                              ; |Buffer = sample.00404AC0

00401667  |.  6A 67         PUSH 67                                           ; |RsrcID = 67 (103.)                //It Actually Never Exist

00401669  |.  57            PUSH EDI                                          ; |hInst = 00400000

0040166A  |.  FFD6          CALL ESI                                          ; \LoadStringW

This  ResourceID   does not Exist .Check the GetLastError  Field Under the ollydbg ERROR_RESOURCE_TYPE_NOT_FOUND.So Look Like A Fake Call   to make Program Look Legitmate(may be)

00401678  |.  57            PUSH EDI                                   ; Arg1 = 00400000        // ImageBase As Parameter

00401679  |.  E8 4DFFFFFF   CALL sample.004015CB    

Trace Into This Call… Again Few Call to  Resources ….LoadIcon,LoadResouce ..Nthing Important

After that We See a call

00401637  |.  50            PUSH EAX                                          ; pWndClassEx = 0006FECC

00401638  |.  FF15 00114000 CALL DWORD PTR DS:[<&USER32.RegisterClassExW>]    ;\RegisterClassExW

Remember  the Address of RegisterClassExW is altered in starting ..Now Instead of Going to user32.dll  ,it points to another function  inside the executable..Trace Into this Function

Here In  this Function We can See Some Interesting Calls  Such As

GetModuleFileNameA=>Here it is  to get the  full path of Currently Executing File (As GetModuleHandleW  with Argument NULL is used to Get Handle For It)

GetTempPathW=> As Name Suggests   Retrieves a  Path  to Temp Files

Then We can see a Call to Function  00401952 =>

I  Checked this Function ..This  internally Calls CRT function _vsnwprintf…Which is used  For String Manipulation (String Formatting)..

First Call  to this Function Returns  =TMP1CDFDEBF (It is Directory name..i know it as I analyzed it )

Second Call To This Function  Returns a String = C:\\DOCUME~1\\ADMINI~1\\LOCALS~1\\Temp\\\\TMP1CDFDEBF

This LookLike A Location To Drop A File

 00401A7D  |.  6A 00         PUSH 0                                                ; /pSecurity = NULL

00401A7F  |.  8D85 F4FDFFFF LEA EAX,[LOCAL.131]                                   ; |

00401A85  |.  50            PUSH EAX                                              ; |Path = “C:\\DOCUME~1\\ADMINI~1\\LOCALS~1\\Temp\\\\TMP1CDFDEBF”

00401A86  |.  FF15 08104000 CALL DWORD PTR DS:[<&KERNEL32.CreateDirectoryW>]    

So  Here it Creates A Directory ..Nthing to Explain..

Then Again  it Call to 401952(String Formatting) to Generate File  Path ..output is


So finally this is Path to Drop File

As Shown in Pic ..then Finally there is call to CopyFileW ..So finally it Drops File to  Location Mentioned above..It Actually Copy/Drop the Same File That is  being Executed ..

So After Dropping A File Our Function Ends ..

So Till Now We Analyzed the RegisterClassExW_0 Function   … Now Trace Into  CreateWindowEx_MOD(Modified CreateWindowEx)…I Call this Function  CreateWindowEx_MOD as it internally Calles  Modified CreateWIndowExW API..

Lets Trace Into This

All  Parameters Original/Necessary  are passed to CreateWindowEx  to make it Look genuine ..Now  Step Into  CreateWindowExW

So   inside CreateWindowExW(that actually is Function  00402228)..We can See some Intersting API Calls

Such As  CreateProcessW,GetThreadContext,SetThreadContext, ,WriteProcessMemory…Lets Check what They Exactly Doing ..

Then  we have a call to   CreateProcessW(W  in the end is to indicate  a Unicode Version)… CreateProcessW  in simple words  used to Create a Process …check MSDN For Other info

Lets Check  the  Paramters Passed to CreateProcessW

Lets Check  the  Paramters Passed to CreateProcessW

00402266  |.  50            PUSH EAX                                              ; /pProcessInfo = 0006FB90

00402267  |.  8D85 D8FCFFFF LEA EAX,[LOCAL.202]                                   ; |

0040226D  |.  50            PUSH EAX                                              ; |pStartupInfo = 0006FB90

0040226E  |.  56            PUSH ESI                                              ; |CurrentDir = NULL

0040226F  |.  56            PUSH ESI                                              ; |pEnvironment = NULL

00402270  |.  6A 04         PUSH 4                                                ; |CreationFlags = CREATE_SUSPENDED 

00402272  |.  56            PUSH ESI                                              ; |InheritHandles = FALSE

00402273  |.  56            PUSH ESI                                              ; |pThreadSecurity = NULL

00402274  |.  56            PUSH ESI                                              ; |pProcessSecurity = NULL

00402275  |.  56            PUSH ESI                                              ; |CommandLine = NULL

00402276  |.  68 80464000   PUSH sample.00404680                                  ; |ModuleFileName = “C:\\DOCUME~1\\ADMINI~1\\LOCALS~1\\Temp\\\\TMP1CDFDEBF\\sample.exe”

0040227B  |.  FF15 40104000 CALL DWORD PTR DS:[<&KERNEL32.CreateProcessW>]        ; \CreateProcessW

The Paramters Highlighted in Red Color are  Important …Let me explain it

00402270  |.  6A 04         PUSH 4                                                ; |CreationFlags = CREATE_SUSPENDED 

Acc.  To MSDN



The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called.

Hope it is  Clear Now….In Case of Malware if Process  is created in SUSPENDED mode then it Most probably  means it will be modified

Other interesting Paramter is

00402276  |.  68 80464000   PUSH sample.00404680                                  ; |ModuleFileName = “C:\\DOCUME~1\\ADMINI~1\\LOCALS~1\\Temp\\\\TMP1CDFDEBF\\sample.exe”

So this mean our sample file starts the dropped file into SUSPENDED Mode …

*Also u can think like that …what is meaning of  dropping  Duplicate/Same File and then Run it ..Does not  making sense ..Dropping File and then run it ..then again  the file will do same (Off course u can think  that file can check its running location and can change its behavior acc. To it but it is not in this case..)…So  it will be  kind of very Stupid malware that Just Drops itself and do nthing ..:P.. so this Philosophy also provide some hint that there will be some modification  in the Dropped File Process..Also We can See Some APIs Like WriteProcessMemory

WriteProcessMemory is  basically used  for InterProcess Communication …to Write the Given Data  in Desired Location in Remote Process.

So All this make Sense that Our   malware will make Some Modification in its child Process i.e Dropped File Process .Lets Continue Analyzing

00402287  |.  50            PUSH EAX                                              ; /pContext = 0006FBE8

00402288  |.  FFB5 24FDFFFF PUSH [LOCAL.183]                                      ; |hThread = 00000048 (window)

0040228E  |.  C785 30FDFFFF>MOV [LOCAL.180],10007                                 ; |

00402298  |.  FF15 74104000 CALL DWORD PTR DS:[<&KERNEL32.GetThreadContext>]      ; \GetThreadContext

GetThreadContext = Retrieves the context of the specified thread  (Simple and smart Defination from MSDN)

pContext = Holds the   CONEXT Structre..I.e it Value Of registers obtained ..Here it is 006FBE8

hThread =Handle of thread….Here in this Case it  Contains the Handle of main thread of Dropped File Process(I will call it Dropped Process  )

Check Context Structre in Windbg ..WIndbg is Pretty Handy Tool to Examine  the Data Structres  in Windows ..also Shows Offsets   …that’s Really Useful…

As You can See  EAX is  at offset 0xB0 ..

We have Context  Structre Starting at    006FBE8

Context.EAX in Memory  = 006FBE8+B0=006FC98

Why EAX is So Important  …  in Case of SUSPENDED Process EAX Always Point  To Entry Point

After Executing GetThreadContext

We  Have   Value of  Context.Eax

We have  006Fc98 = 004029B9 ..As Described Earlier it is Entry Point of Dropped Process

Now Examine  Next  Few  Intersting  Lines

004022A4  |.  50            PUSH EAX                                              ; /pContext = 0006FBE8

004022A5  |.  FFB5 24FDFFFF PUSH [LOCAL.183]            ; |hThread = 00000048 (window) //Dropped  Process thread

004022AB  |.  C785 E0FDFFFF>MOV [LOCAL.136],sample.00401E1F                      //OverWrite EAX

004022B5  |.  FF15 70104000 CALL DWORD PTR DS:[<&KERNEL32.SetThreadContext>]     

SetThreadContext= Sets the context for the specified thread….

As You Can See   it Points to Same    Address  0006FBE8

Check the Highlighted… Here LOCAL.136 = 006Fc98 ..So what this instruction doing is  Overwriting the value at  Location 006Fc98  with   00401E1F..

And   Then  We have a call to SetThreadContext…

So     all this to change the Entry Point of Dropped Process By  Overwriting the Eax in Context Structre.

Check the Below  Snapshot    to get things more Clear way …IDA’s  naming feature  make this tool ideal for reversing .

So  Entry Point is Changed …Lets see what happened Next..Lets Analyze what happen Next

004022C1  |.  56            PUSH ESI                                          ; /pBytesWritten = NULL

004022C2  |.  68 08020000   PUSH 208                                          ; |BytesToWrite = 208 (520.)

004022C7  |.  B8 A0484000   MOV EAX,sample.004048A0                           ; |UNICODE “C:\\Documents and Settings\\Administrator\\Desktop\\97c5080399e5df2407d6fdf28faf17f8\\1d8ea40a41988b9c3db

004022CC  |.  50            PUSH EAX                                          ; |Buffer = sample.004048A0

004022CD  |.  50            PUSH EAX                                          ; |Address = 4048A0

004022CE  |.  FFB5 20FDFFFF PUSH [LOCAL.184]                 |hProcess = 00000044      //Handle of  Dropped Process

004022D4  |.  FFD3          CALL EBX                                          ; \WriteProcessMemory

As I commented  hProcess  is Handle of Dropped Process…So what  WriteProcessMemory Here Doing is  Copying  the   Orginal Path of Sample  To Dropped Process.(4048A0 contains path of Current Executable).You will come   to  know why  this is copied to dropped process

Call  to GetCurrentProcessId  = This  Returns  the Process ID of Current Process in Eax

Next , OpenProcess API is called and ProcessID of Current  Process is Passed a Parameter..This Means OpenProcess Attempt to  Currently Executing Process with PROCESS_ALL_ACCESS (Red mark 1F0FFF=PROCESS_ALL_ACCESS)…If Evrything Fine then OpenProcess Will Return A handle to  Local Process Object.

Next We Have a Call to DuplicateHanlde…This is Best Explained  in MSDN ..Read it

Then  we  have a call to WriteProcessMemory…In this  call..we are Passing the Real Handle Obtained  By Using DuplicateHandle to Dropped Process.. We Write The Handle at =404AA8  (Keep this in Mind)

If u read the MSDN  ..then the Purpose of this WriteProcessMemory will be Clear  to You ..

Then We have a call to  Resume Thread

0040231A  |.  FFB5 24FDFFFF PUSH [LOCAL.183]                    ; /hThread = 00000048   //Dropped Process

00402320  |.  FF15 1C104000 CALL DWORD PTR DS:[<&KERNEL32.ResumeThread>]

So  Finally  After making all the Necessary Changes  in Dropped Process …It Resumes The  Dropped Process and then Dropped Process Start Executing  ..

I  did not execute ResumeThread  Till Now …All I want is  to attach Ollydbg to  to dropped process..

Here is a way how to do it ..

We have  entry point  of   Dropped Process =401E1F h

So what we are Going to do is  to trap the    the   Dropped Process in Infinite Loop…

I am going to Use PUPE  Suite  .. And  Chaned First Two Bytes at  401E1F  to EB FE  (Write Down Orginal Bytes Before Changing Orginal Ones)

Check  my previous post  where i use same method    if  you are not getting it

 So Now Execute ResumeThread.Now  Dropped Process is Trapped in  Infinite Loop..Attach Ollydbg to it ..Replace EB FE  with Orginal Bytes (orginal Bytes : 8B FF)..

*I  Recommend to DUMP the Process  at this point as I include all the changes made by parent process..we are going to analyze this dumped  process in next part of this series

So Finally What we have is  Two Instances of Ollydbg   one  Debugging  sample and other Debugging  Dropped Process.

This is What We have in Sample Process…After Resuming  Main Thread of Dropped Process …it closes   Hanldes and Finally Exits

Look at Code From Dropped Process

So What We have Calls To Memset ..After Memset Calls We have Very Intersting  API Call

WaitForSingleObject (hObject,TimeOut)

hObject=404AA8 (Remember 2nd WriteProcessMemory Call ,Where we  Write the handle obtained from DuplicateHandle    at  404AA8  of Dropped Process)

TimeOut = INFINITE  // Wait Until  Object is Signaled

And After that   Handle is Closed  by Using CloseHandle

Then We Have  a Call to  DeleteFileW …The Filename passed is Location of   Sample Process

*Remember  when we passed the location/path of sample  Executable using first WriteProcessMemory Call

So I think Now it is clear how this   implement Self Delete(Melt Feature)/Drop File …

Dropped Process Wait for the  Event From  Sample Process …When it is Signaled it go ahead and delete that file.

So  First Part Ends Here …In Next Part We Will Analyze the Dropped Process(I Dumped it when I restore the orginal Bytes  after attaching Ollydbg to it).

I  Love to  get Your Feedback .You can Email me or    Comment on  my blog

Email Id :



Tools Used



2)Process Explorer




4)PE Tools


5)Hex WorkShop



So what is a Crypter.If   have some  experience in malware Field  then You must have Heard about  tool called “Crypter”or may be used it.The Aim of Crypter to Protect the  executables ,making  difficult to analyze it or reverse engineer it .But Mostly in Malware Scene  the crypters are  mainly used to make malwares FUD .Here FUD stands for  Fully Undetectable.

Actually  the malware are basically distributed as  executables ,I mean sources are gernally not available.  Public  malwares are  gernally detected by antivurses  ,that’s why crypters are used to make them FUD .

How Crypters  Work

Principle for making a crypter is very simple . Crypter  Consist of Two parts



How they both parts work

1)You give  your file as input to crypter,it encrypts it  with any encryption algorithm (most likely  RC4,AES)

By encrypting the file it defeat the static analysis done by antivirus.During static analysis the antivirises  try to find the  the patterns in executable and match with with  signatures.Because the file is encrypted

So the antivirus can’t find patterns  here.

2)Add  the stub  before the executable code.

When  you run  executable  then the stub runs and decrypt the encrypted file .

Note :The decrypted file remains in memory .

3)Execute the Decrypted from Memory .

This  is actually the heart of crypter.This is also called “Run PE  “.There are different methods for Run PE .But  Mostly the Crypter used a public method   to exectute the File from Memory ,that’s what we are going  to target.

Let me Explain the  the method .The orginal  link of this method is

I  just copying the steps .i realy suggest you to once read the whole  article to understand in more depth.

The steps listed in article are :

1)      Use the CreateProcess API with the CREATE_SUSPENDED parameter to create a suspended process from any EXE file. (Call this the first EXE).

2)      Call GetThreadContext API to obtain the register values (thread context) of the suspended process. The EBX register of the suspended process points to the process’s PEB. The EAX register contains the entry point of the process (first EXE)

3)      Obtain the base-address of the suspended process from its PEB, i.e. at [EBX+8]

4)      Load the second EXE into memory (using ReadFile) and perform the neccessary alignment manually. This is required if the file alignment is different from the memory alignment

5)      If the second EXE has the same base-address as the suspended process and its image-size is <= to the image-size of the suspended process, simply use the WriteProcessMemory function to write the image of the second EXE into the memory space of the suspended process, starting at the base-address

6)      Otherwise, unmap the image of the first EXE using ZwUnmapViewOfSection (exported by ntdll.dll) and use VirtualAllocEx to allocate enough memory for the second EXE within the memory space of the suspended process. The VirtualAllocEx API must be supplied with the base-address of the second EXE to ensure that Windows will give us memory in the required region. Next, copy the image of the second EXE into the memory space of the suspended process starting at the allocated address (using WriteProcessMemory)

7)      Patch the base-address of the second EXE into the suspended process’s PEB at [EBX+8]

8)       Set EAX of the thread context to the entry point of the second EXE

9)      Use the SetThreadContext API to modify the thread context of the suspended process

10)  Use the ResumeThread API to resume execute of the suspended process.

When you normally  load a packed executable in ollydbg then it shows warning like “the code section is compressed” or “the entrypoint is outside  the code section “ whatever means olly give you hint that the  executable is packed.But  the executable crypted by crypter (which is using above method) never shows any warning when it is loaded into olly it does not show any warning .


Here is a target Link


NOTE : The target is detected as  malware by antivirus  beaucse it is crypted by using public crypter .Dont worry   this is simple  and clean application. But i strongly suggest you to using vmware or virtualbox .

Lets start from very basic stuff ,Scan it with PEID

Looks  Inocent 😛 ,is it ?

Lets Load it in Olly ..see it shows any warning or not

Everthing Looking normal,Looks Like a normal VB excutable no  warning shown by olly

First Verify If our target is realy innocent or malicious.Acc. to method described above it must call Create a new process.So Put a BP on  CreateProcessA  and CreateProcessW  (for both ascii and unicode versions).If it Breaks then see the arguments passed check if it is in SUSPENDED MODE (Also You can Put Breakpoint on ReadProcessMemory and WriteProcessMemory APIs to  check it more accurately )

I Put BP on CreateProcessW and CreateProcessA  and run it in olly.As you can see this it is Breaked at CreateProcessA..Also You can  see it parameters in stack ,also you can see that it is in SUSPENDED_MODE .

It calles the CreateProcess In suspended mode(suspend its  main thread) then decrypt the encrypted malware in newly created process address space  when everything is on its place then   it calls the ResumeThread API and it start running

We are going to  attack at the point when It calles the ResumeThread API,because ResumeThread API is last step in executaion and before this everthing will be on its place .

So I Put BP on ResumeThread,Lets See  what Happens

Wow Its Breaked  on ResumeThread..

Now Step Into ResumeThread  by Pressing F7.

As You can see that ResumeThread  internally calls window native api NtResumeThread

NOTE: NtResumeThread is Undocumneted  native API . Most of windows API works this way .They provide a documented interface for main function then internally called the undocumented native APIs.This Concept is very Important Because Sometime  the Crypter  authors uses undocumented  native APIs instead of Documented APIs.

For example  they can directly use NtResumeThread instead of calling ResumeThread.In this way if you put BP  on  ResumeThread then it will not break .So I strongly suggest you to put breakpoint  on native undocumented APIs instead  of Documented APIs.

For example always put BP on NtResumeThread instead of ResumeThread ,then you  will directly break at 75A0C3D5 instead of  75A0C3C9

Lets  Step inside NtResumeThread. By pressing F7.Contnue pressing F7  until  you reach it 778764F2

This is point where the ResumeThread actually get executed  and our suspended Process will start executing ,but we do not want to execute it  to not get infected .So   stop Here

Now open  the Process Explorer and dump the  this process (the  child process),select child process ,select  full dump

It will be  saved as filename .dmp format ,I rename it to dump.exe

I named file as dump.exe  ,and I scan it with PEID

Ah, not a Valid PE file..seems scary  ..lets Fix this..The PE File start With  Letter “MZ “.The File Analyzer like PEID gernally  first check if the file contain MZ  in starting or not ..if not  that mean not a valid PE file(Also they do some extra tests ..but check for   ”MZ” is  first one.)

Open Up it dump.exe in Hex Workshop,search for  “MZ”.Delte  Everything above  “MZ”.  Save It ,Then our file become  valid executable .

Now You can scan your modified  File with PEID .Just see the results i got

Now Look Like Valid PE  😀

But this is Not  runing   and giving the C++ Run time Error

If  this file is not going to run then why we waste so much time on it ?

The Purpose  of making this valid PE is to Find Its OEP  by Loading it into Olly or by using other PE utlity tools

Note : You can find directly Calculate OEP from Hex Workshop without Deleting the Bytes  If You know PE  Header, I want to make it simple so I do it by this simple ad long way.

OEP :Orginal Entry Point .It is  the address from which  the program start execution.

Why we need OEP  ?

WE Dump the  program before the ResumeThread execute  but it is not working.I   am supposing the the crypted program is malware so I do not want to run it,then how I am going to to get  it working .The idea is

Change the First Two Bytes  at Program Entry point so that it trapped in infinite LOOP   ,this way it will not able to get executed and  everthing will be placed correctly and we  will have a gud chance to dump  it .

Lets Find the OEP by   of our dumped file by opening it in olly.Also Note Down the starting  bytes at entry point

0048847F <ModuleEntryPoint>          6A 60           PUSH 60

EntryPoint  0048847F

The First Two Bytes are  6A 60

Show Time

Lets  Finally Fix this

Run the Crypted.exe in olly  ,Continue Untill the last instruction inside ResumeThread  Executes  Like we did before.

That is

countinue  Stepping into ResumeThread API until this instruction

7C90EB8D      0F34                      SYSENTER

That’s point where the actually execuation takes place

Now We Have to  change first two bytes at EntryPoint to trap the program in  infinite Loop,we olly use the  little program PUPE for this

We can see our child process Crypted.exe in process Explorer. Its process id is 544 in decimal

Process id in Hex =220

Select the Target  Process and click Patch   . Then You will  see the patch window   Like this

Change the Number of bytes to  2

Put the OEP  in the Direction  option and click search    we get 6A 60 as bytes  (these are ogrinal bytes .note  it )

Put   EB FE  in change  by .

EB FE will  instruction will make the  jump to  to same instruction again and again and hence trap it in infinite loop

Now click on patching

After that the orginal  bytes are replaced by EB FE    .

Now Go to our ollly again  and click and Run the Program

After Clicking on Run button  you will see that  that your process is terminated in olly .

Don’t Worry  it does not matter to us .Only child process matter to us that is still running  (trapped in infinite loop) . Now you just have to Dump it with Your Favourate Dumping tool. I Will dump it with my favourate that is  PE tools

Click on Dump Full and save it with any name you want .i saved it with final_dump.exe

After Dumping Also Kill the  process.

Now open the final_dump.exe in olly

As You can see the first two bytes are EB FE   ,they will always trp the program in infinite loop  to fix it replace these two bytes with orginal two bytes that are   6A 60

Right   click on instruction then go to binary -> edit options and replace it with  orginal bytes  as shown in pic

Now  click on the  copy to executable  option  and save this file .Now You have Your orginal file back .

Congrats You just Unpck the crypted file successfully.

You can verify it  by running .

Important :

As I already mention  the crypter coders now days use the  windows undcoumneted  native APIs instead of  documented API

 FOR example Use of NtResumeThread   instead of ResumeThread.

So I suggest to Put BP on NtResmeThread instead of Resume Thread.

Apply  same to all other API that you want to break on .

These crypters gernally add junk code    to make them undtectbale but don’t worry if they are using the same  RUN PE method they will get unpacked by using this method because  adding junk code did not matter at the end they have to to call  ResumeThread  😛

NOTE  :This Method works on the crypter who are using  the  above   method written  .I   found  that more than 60 % crypters use the  method.

If You like My tute then leave comments or you can mail me  .

Solving Crackme 1

Hello Friends,this is the first tutorial of series.I find about a series of serial fishing on along with solutions.It is just great for beginers.There are Multiple ways to crack a program.I will share the solution to some selected crackme’s given in series .i also recmend you first to try crackme yourself …check the solutions only if u are not able to solve it.i also recmend you to also check the solutions given on,more the ways you learn more you understand(also they are videos) thread Link

So lets start .This is first crackme… You can get it from here

I assume You are Familier with Ollydbg and basic asm syntax.Also with some basic APIs
So not wasting much of our precious time.Lets start

What crackme need

Lets see what the crackme is asking for ,see the image

It is asking for password ..i just put 123456 and press check.and it is showing the MessageBox titled “wrong”.I realy hate this thing lets fix this shit.

It is always useful to check wheather the program is packed or not(we will discuss about packing and unpacking later),also to check for language in which the program is compiled.
How this can help.By Knowing the language we can use the tools which are made for specific languages.Like VB decompiler,SmartCheck For Visual Basic,DeDe For Delphi.So knowing the languages in which the program is compiled matters.Also Every Languages have different patterns also there are some language specific it is good practice to know about the compiler of target .
I am using a famous toold peid for this purpose. So lets start

Nothing Found !!.This can Happen sometimes.Peid actually stroes the patterns generated by different compilers at compile time and try to match it with target executable and depending on the match show the results.But it is easy to play with signatures and modify and change them…we will discuss it later.Lets check in another similar tool like peid.Lets see if it works.Scan the crackme with ExeInfo.


MicroSoft Visual C++ or Masm 5.12 .Looks Confused.Any way we can also guess the language by looking at disasmblly inside ollydbg.
Lets Load it in olly.


It is look like written in Masm.How can we say this.The high Level Languages Like Visual C++,Delphi include different methods for initializing the program for example c run time library functions.Masm gernally do not add extra code .The program will shown in disasmbly as it is actually written .
So we have classic MASM lets start .Our main goal is to locate the part of program in which the serial is checked and this badboy is showed up.


1)Run the program in olly .it will ask for password .enter any wrong password and press check button.
2)it will show badboy then Just pause the olly ,and press ALT+F9.
3)Then Press “ok” button on badboy messagebox.The olly will leads you to the place from which the messagebox is originating.

See the Pic

Here we are,olly leads me to 004010D8 location ,this is the next instructions after “MessageBox” API.
Here We can see Two MessageBoxes ,You can see Clearly one is having the “Right” title and another one is titled “wrong”.We want goodboy i.e MessageBox with “right”.See Carefully at location 004010AE ,there is conditional jump.Put a BreakPoint on it just by Double Clicking the Opcode Window and Restart the Program.Agin Put any fake serial number and Press Check button .y0,we hit at the breakpoint.Our program breaked at location 004010AE at conditional Jump(JNZ).

JNZ basically checks Zero Flag to Jump .(Jump if not Zero,Jump if zero Flag is not set)
You can clearly see that that JNZ is deciding wheather we get goodboy or badboy.At this time zero flag is not set so surely we will get jump and get badboy.To get Goodboy just set the zero flag and you done.Click on the “0” infront of “Z” as highlighted in Pic and it will become 1 and zero flag is now set.

Also See the Pane window to check wheather the jump is taken or not. So jump is not taken and we will get our goodboy.Just run the program and see.

Yep we got our goodboy.Is this tute is only about to get a goodboy message by patching a conditional jump .The answer is No .we Will go deep,we will analyze why jump is taken before reaching at our breakpoint.Why our serial is rejected(so sad).
Scroll up and you will see a CMP (comparion) instrtion at 004010AB.It is used To Compare two values and set the zero flag as the result.The instruction is

Cmp eax,1
It is comparing eax with 1.
Output of the the above written instruction will be
If eax is greater than or smaller than 1 then unset the zero flag.
If eax is equal to 1 then set the zero flag.

So  we need eax to be 1 to get o our goodboy.But from where  the eax is getting value.

Just see the above instruction  at 004010A6. It’s a call instruction means it is for  calling a function

Also You an see  a PUSH at 004010A1.Olly is Intelligent Enough to show us what it is being pushed .When it ask for password I enter “123456”.So my enterted serial number is begin pushed into stack.

This PUSH  actually acts as  parmeter to function which we are calling in next instruction.

How we call function in C.

Myfunction(parameter 1,parameter 2)

How we call function in asm.

PUSH parameter 2

PUSH parameter 1

Call  Myfunction

I Hope Now you understand  what is meaning of  instructions at 004010A1, 004010A6.The function called at 004010A6  is getting serial entered by me as parameter.So this function is looking  like serial verifier function  ..isn’t.Let see.

Put Breakpoint  at 004010A6 and rerun  the program.Enter your fake serial ,I entered  “123456” and  press “check” button. SO we Breaked at 004010A6.Press F7 to  step into the function code.

Execute instructions pressing F8 untill  00401101.

At  00401101   PUSH ESI   (Saving the orginal value of ESI in stack)

00401102  MOV  ESI ,[ARG.1]  (Moving the  argument passed  into ESI(remember the argument was our fake serial, you can see this in pane window. Sorry I miss that in screen shot)

00401105 Call g1.0040110F    (call to function)

0040110A  POP ESI               (Get orginal value back from stack)

So  our fake serial is moved into ESI and function  is called.Lets see what is happening inside the function by stepping into function by pressing F7.

Wow ,can you see a  dark line from  0040111E  to 0040112E.This Indicates a Loop.Loop is simply to repeat the process until a condition is met(use google  for more detailed information).Mostly serial Comparisons are Done Inside Loops.So pay  special attention to loops.

Also  we can see xor instructions.

Xor eax,eax (Xoring with same register will make that register zero)

So all 3 xor instruction are to make ecx,eax,ebx  zero.


Now people can ask why we just can’t  move zero to register Like

Mov eax,0

This is so simple and also  producing same result.But  this instruction  is 5 byte instruction.where xor  eax,eax is 2 byte instruction.

There is something called compiler optimizations  due to which  compiler choose the short instructions to get work done more efficiently.

Ques:>How can we know how much bytes each instruction is having…

Ans=> Just look at opcode window  or just yo can subtract the address of  your instruction from address of next instruction.

See  at  00401117    mov edi,g1.00401138  (a constant string is moved into EDI.ollydbg  show  the string moved is  “Ndg6kP”)

Execute this instruction. Now we got jmp to  0040112b .Instruction at 0040112b is

0040112b Cmp ecx,6

0040112e  jb  short  g1.0040111E

JB  check carry flag to decide jump or not.

You remember  0040111E is starting of loop. so  these instruction means

Jump to starting to loop until  Cmp  ecx,6  results  carry.

(Cmp instruction actually subtractes the  operands then set appropriate  flag here it will be ecx-6 it will set carry flag until ecx is 5 or less than 5 )

Now AnaLyze the Loop

Here  we can see the value of  ESI,EDI ,ECX  in olly Registers Window.

ESI contains   our fake serial that is “123456”

EDI contains a text  “Ndg6kP”

ECX ,EAX,EBX are 0.

0040111E             MOV AL,BYTE PTR DS:[ECX+ESI]

00401121             MOV BL,BYTE PTR DS:[ECX+EDI]

These instructions means  moving a single byte(a char is of single byte(ascii) ) into al,bl from [ECX+ESI ] and  [ECX+ESI] ,Ecx  is zero so    the first char that is “1” ( ascii value of 1 )    is  moved into al.

Similarly “N” (ascii value of “N”) is moved into  bl.

00401124             INC BL  (increment BL  ,in this case ascii value of “N”+1)

00401126             CMP AL,BL   (comare al and bl)

00401128           JNZ SHORT g1.00401138 ( conditional jump,if al,bl are not equal then jump to 00401138n else not  jump)

What if jmps then

00401138   MOV EAX,0

0040113D   POP EDI                            

0040113E   POP ESI                            

0040113F   RETN

Move  0 into eax  ,restore values of esi and edi and loop  function returns.U  remember we did all analysis to find where eax is getting this place  where eax is  getting zero .

What if not jumps

0040112A                                    INC ECX   (increment Ecx)

0040112B                                  CMP ECX,6  (compare  ecx with 6)

0040112E                                  JB SHORT g1.0040111E (jmp until carry)

Ecx increments,and will used to  get next char of   string in ESI and EDI. Ecx keep incrementing  till 5.

If loops terminates then  we have these instructions

00401130   MOV EAX,1

00401135   POP EDI                             

00401136   POP ESI                            

00401137    RETN

Everthing is almost same  as 00401138 ,just instead of 0  ,1 is moved into eax.that will  lead to goodboy.You can see this  snapshot for more understanding

How serial is Genrated

So Now we understand how things work .Lets write it in more clearer manner ,and how serial is generated

1)      first “Ndg6kP”  is loaded

2)      char is moved   and 1 is added

3)      points to next char

repeat  step 2,3  5 times

(because loop starts with ecx   having value 0 and runs until  ecx is having 5 ,and ecx is incremented once in each iteration .so 0 to 5 = 6 times)

What is serial

We just having to shift each char of “Ndg6kP”   by 1.



“g”+1 =”h”




So final serial is  “Oeh7lQ”.Check it in  our  crackme.

Patching Solution:-

Multiple Patching solution Exists ..i discuss  2 of them

1)      AT   00401138

00401138   MOV EAX,0

Here move 1 instead of 0

Mov EAX ,1


00401128   JNZ SHORT g1.00401138

Replace this with NOP.

This way loop ends  correctly whatever serial  you insert.


Hope You Enjoy my tutorial.I love to have your feedback .If you like or dislike  this post then comment and let me know .