; ; +-------------------------------------------------------------------------+ ; | This file is generated by The Interactive Disassembler (IDA) | ; | Copyright (c) 2007 by DataRescue sa/nv, <ida@datarescue.com> | ; +-------------------------------------------------------------------------+ ; CODE:00402480 CODE:00402480 ; =============== S U B R O U T I N E ======================================= CODE:00402480 CODE:00402480 ; Attributes: bp-based frame CODE:00402480 CODE:00402480 ; int __stdcall launch_image_in_memory(CONTEXT hProcess) CODE:00402480 launch_image_in_memory proc near ; CODE XREF: CODE:00402D49p CODE:00402480 CODE:00402480 hProcess = CONTEXT ptr -148h CODE:00402480 CODE:00402480 ; FUNCTION CHUNK AT CODE:00401A3C SIZE 00000036 BYTES CODE:00402480 CODE:00402480 000 push ebp CODE:00402481 004 mov ebp, esp CODE:00402483 004 add esp, 0FFFFFEB8h CODE:00402489 14C push ebx CODE:0040248A 150 push esi CODE:0040248B 154 push edi CODE:0040248C 158 mov dword ptr [ebp+hProcess.ExtendedRegisters+70h], ecx CODE:0040248F 158 mov dword ptr [ebp+hProcess.ExtendedRegisters+74h], edx CODE:00402492 158 mov dword ptr [ebp+hProcess.ExtendedRegisters+78h], eax ; ExtendedRegisters+0x78 is initialized with a pointer CODE:00402492 ; to the decrypted embedded executable in heap space CODE:00402495 158 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+74h] CODE:00402498 158 call sub_401EF8 CODE:00402498 CODE:0040249D 158 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+70h] CODE:004024A0 158 call sub_401EF8 CODE:004024A0 CODE:004024A5 158 xor eax, eax CODE:004024A7 158 push ebp CODE:004024A8 15C push offset loc_4026F0 CODE:004024AD 160 push dword ptr fs:[eax] CODE:004024B0 164 mov fs:[eax], esp CODE:004024B3 164 xor ebx, ebx CODE:004024B5 CODE:004024B5 ; init ExtendedRegisters CODE:004024B5 CODE:004024B5 164 lea eax, [ebp+hProcess.ExtendedRegisters+44h] CODE:004024B8 164 xor ecx, ecx CODE:004024BA 164 mov edx, 10h CODE:004024BF 164 call c_memset ; eax = buffer CODE:004024BF ; edx = count CODE:004024BF ; ecx = int CODE:004024BF CODE:004024C4 164 lea eax, [ebp+hProcess.ExtendedRegisters] CODE:004024C7 164 xor ecx, ecx CODE:004024C9 164 mov edx, 44h CODE:004024CE 164 call c_memset ; eax = buffer CODE:004024CE ; edx = count CODE:004024CE ; ecx = int CODE:004024CE CODE:004024D3 CODE:004024D3 ; start copy of its own process (suspended!) CODE:004024D3 CODE:004024D3 164 mov dword ptr [ebp+hProcess.ExtendedRegisters], 44h CODE:004024DA 164 xor eax, eax CODE:004024DC 164 mov al, [ebp+hProcess.ExtendedRegisters+84h] CODE:004024DF 164 mov word ptr [ebp+hProcess.ExtendedRegisters+30h], ax CODE:004024E3 164 lea eax, [ebp+hProcess.ExtendedRegisters+44h] ; +0x44 will contain the pid CODE:004024E6 164 push eax ; lpProcessInformation CODE:004024E7 168 lea eax, [ebp+hProcess.ExtendedRegisters] CODE:004024EA 168 push eax ; lpStartupInfo CODE:004024EB 16C push 0 ; lpCurrentDirectory CODE:004024ED 170 push 0 ; lpEnvironment CODE:004024EF 174 push CREATE_SUSPENDED ; dwCreationFlags CODE:004024F1 178 push 0 ; bInheritHandles CODE:004024F3 17C push 0 ; lpThreadAttributes CODE:004024F5 180 push 0 ; lpProcessAttributes CODE:004024F7 184 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+70h] CODE:004024FA 184 call sanitize_eax CODE:004024FA CODE:004024FF 184 push eax ; lpCommandLine CODE:00402500 188 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+74h] CODE:00402503 188 call sanitize_eax CODE:00402503 CODE:00402508 188 push eax ; lpApplicationName CODE:00402509 18C call CreateProcessA CODE:00402509 CODE:0040250E 164 test eax, eax CODE:00402510 164 jz err_createproc CODE:00402510 CODE:00402516 164 mov [ebp+hProcess.ExtendedRegisters+5Bh], 1 ; process_started = true; CODE:0040251A 164 xor eax, eax CODE:0040251C 164 push ebp CODE:0040251D 168 push offset loc_4026CE CODE:00402522 16C push dword ptr fs:[eax] CODE:00402525 170 mov fs:[eax], esp CODE:00402528 CODE:00402528 ; fill context structure of the newly created process CODE:00402528 ; the CONTEXT_INGEGER flag is passed to GetThreadContext() CODE:00402528 ; CODE:00402528 ; #define CONTEXT_i386 0x00010000 // this assumes that i386 and CODE:00402528 ; #define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L) CODE:00402528 CODE:00402528 170 mov [ebp+hProcess.ContextFlags], 10002h CODE:00402532 170 lea eax, [ebp+hProcess] CODE:00402538 170 push eax ; lpContext CODE:00402539 174 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+48h] CODE:0040253C 174 push eax ; hThread CODE:0040253D 178 call GetThreadContext CODE:0040253D CODE:00402542 170 test eax, eax CODE:00402544 170 jz err_ldrfailure CODE:00402544 CODE:0040254A CODE:0040254A ; the loader exploits the fact that ebx points CODE:0040254A ; to the PEB at process start. CODE:0040254A ; so by getting the DWORD pointed to by ebx+8, CODE:0040254A ; the loader retrieves the ImageBaseAddress from CODE:0040254A ; the PEB structure CODE:0040254A ; (http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/PEB.html) CODE:0040254A CODE:0040254A 170 lea eax, [ebp+hProcess.ExtendedRegisters+68h] CODE:0040254D 170 push eax ; lpNumberOfBytesRead CODE:0040254E 174 push 4 ; nSize CODE:00402550 178 lea eax, [ebp+hProcess.ExtendedRegisters+6Ch] CODE:00402553 178 push eax ; lpBuffer CODE:00402554 17C mov eax, [ebp+hProcess._Ebx] CODE:0040255A 17C add eax, 8 CODE:0040255D 17C push eax ; lpBaseAddress CODE:0040255E 180 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+44h] CODE:00402561 180 push eax ; hProcess CODE:00402562 184 call ReadProcessMemory CODE:00402562 CODE:00402567 170 test eax, eax CODE:00402569 170 jz err_ldrfailure CODE:00402569 CODE:0040256F CODE:0040256F ; the virtual address space starting at the CODE:0040256F ; imagebase passed to ZwUnmapViewOfSection is CODE:0040256F ; now being unmapped, which means code/data/etc CODE:0040256F ; of the loaded process are removed. CODE:0040256F ; (http://www.osronline.com/ddkx/kmarch/k111_9oaa.htm) CODE:0040256F CODE:0040256F 170 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+6Ch] CODE:00402572 170 push eax CODE:00402573 174 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+44h] CODE:00402576 174 push eax CODE:00402577 178 call ZwUnmapViewOfSection CODE:00402577 CODE:0040257C 170 test eax, eax CODE:0040257E 170 jl err_ldrfailure CODE:0040257E CODE:00402584 CODE:00402584 ; check if the embedded executable was successfully decrypted CODE:00402584 ; (remember? +0x78 contains a pointer to the embedded PE image in memory) CODE:00402584 CODE:00402584 170 cmp dword ptr [ebp+hProcess.ExtendedRegisters+78h], 0 CODE:00402588 CODE:00402588 ; the code below will get the original imagesize CODE:00402588 ; and imagebase values of the embedded executable CODE:00402588 ; and use them to allocate a new memory block in CODE:00402588 ; the process space of the (still suspended) process CODE:00402588 CODE:00402588 170 jz err_ldrfailure CODE:00402588 CODE:0040258E 170 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+78h] CODE:00402591 ; get offset to PE header CODE:00402591 170 mov eax, [eax+3Ch] CODE:00402594 ; add address of decrypted executable and save it CODE:00402594 ; into the ExtendedRegisters structure CODE:00402594 170 add eax, dword ptr [ebp+hProcess.ExtendedRegisters+78h] CODE:00402597 170 mov dword ptr [ebp+hProcess.ExtendedRegisters+5Ch], eax CODE:0040259A 170 push 4 ; flProtect CODE:0040259C 174 push 3000h ; flAllocationType CODE:004025A1 178 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+5Ch] CODE:004025A4 ; get image size from PE header CODE:004025A4 178 mov eax, [eax+50h] CODE:004025A7 178 push eax ; dwSize CODE:004025A8 17C mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+5Ch] CODE:004025AB ; get image base from PE header CODE:004025AB 17C mov eax, [eax+34h] CODE:004025AE 17C push eax ; lpAddress CODE:004025AF 180 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+44h] CODE:004025B2 180 push eax ; hProcess CODE:004025B3 184 call VirtualAllocEx CODE:004025B3 CODE:004025B8 170 mov dword ptr [ebp+hProcess.ExtendedRegisters+6Ch], eax CODE:004025BB 170 cmp dword ptr [ebp+hProcess.ExtendedRegisters+6Ch], 0 CODE:004025BF 170 jz err_ldrfailure CODE:004025BF CODE:004025C5 CODE:004025C5 ; write headers of the image CODE:004025C5 CODE:004025C5 170 lea eax, [ebp+hProcess.ExtendedRegisters+64h] CODE:004025C8 170 push eax ; lpNumberOfBytesWritten CODE:004025C9 174 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+5Ch] ; ptr to PE header of decrypted executable in memory CODE:004025CC ; get SizeOfHeaders CODE:004025CC 174 mov eax, [eax+54h] CODE:004025CF 174 push eax ; nSize CODE:004025D0 178 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+78h] ; ptr to decrypted image in memory CODE:004025D3 178 push eax ; lpBuffer CODE:004025D4 17C mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+6Ch] ; virtual address to write to CODE:004025D7 17C push eax ; lpBaseAddress CODE:004025D8 180 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+44h] ; pid CODE:004025DB 180 push eax ; hProcess CODE:004025DC 184 call WriteProcessMemory CODE:004025DC CODE:004025E1 170 test eax, eax CODE:004025E3 170 jz err_ldrfailure CODE:004025E3 CODE:004025E9 170 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+5Ch] CODE:004025EC 170 call get_address_of_section_table ; in: eax = ptr to PE header CODE:004025EC CODE:004025F1 170 mov esi, eax CODE:004025F3 170 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+5Ch] CODE:004025F6 ; get number of sections CODE:004025F6 170 movzx eax, word ptr [eax+6] CODE:004025FA 170 dec eax CODE:004025FB 170 test eax, eax CODE:004025FD 170 jb short err_no_more_sections CODE:004025FD CODE:004025FF 170 inc eax CODE:00402600 170 mov dword ptr [ebp+hProcess.ExtendedRegisters+54h], eax ; number of sections to patch into process CODE:00402603 170 xor ebx, ebx CODE:00402603 CODE:00402605 CODE:00402605 ; copy each section of the embedded executable CODE:00402605 ; into the process space CODE:00402605 CODE:00402605 CODE:00402605 insert_section_into_process_space: ; CODE XREF: launch_image_in_memory+1D6j CODE:00402605 170 lea eax, [ebp+hProcess.ExtendedRegisters+64h] CODE:00402608 170 push eax ; lpNumberOfBytesWritten CODE:00402609 174 lea edi, [ebx+ebx*4] ; edi = number of current section * 5 CODE:0040260C 174 mov eax, [esi+edi*8+10h] ; size of raw data of n-th section CODE:00402610 174 push eax ; nSize CODE:00402611 178 mov eax, [esi+edi*8+14h] ; pointer to raw data of n-th section CODE:00402615 178 add eax, dword ptr [ebp+hProcess.ExtendedRegisters+78h] CODE:00402618 178 push eax ; lpBuffer CODE:00402619 17C mov eax, [esi+edi*8+0Ch] ; virtual address of n-th section CODE:0040261D 17C add eax, dword ptr [ebp+hProcess.ExtendedRegisters+6Ch] CODE:00402620 17C push eax ; lpBaseAddress CODE:00402621 180 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+44h] CODE:00402624 180 push eax ; hProcess CODE:00402625 184 call WriteProcessMemory CODE:00402625 CODE:0040262A 170 test eax, eax CODE:0040262C 170 jz short err_writeprocmem CODE:0040262C CODE:0040262E CODE:0040262E ; convert section characteristics to CODE:0040262E ; memory protection "characteristics" CODE:0040262E CODE:0040262E 170 lea eax, [ebp+hProcess.ExtendedRegisters+60h] CODE:00402631 170 push eax ; lpflOldProtect CODE:00402632 174 mov eax, [esi+edi*8+24h] ; characteristics of n-th section CODE:00402636 174 call convert_section_characteristics_2_memory_protection CODE:00402636 CODE:0040263B CODE:0040263B ; apply memory protection "characteristics" CODE:0040263B CODE:0040263B 174 push eax ; flNewProtect CODE:0040263C 178 mov eax, [esi+edi*8+8] ; virtual size of n-th section CODE:00402640 178 push eax ; dwSize CODE:00402641 17C mov eax, [esi+edi*8+0Ch] ; virtual address of n-th section CODE:00402645 17C add eax, dword ptr [ebp+hProcess.ExtendedRegisters+6Ch] CODE:00402648 17C push eax ; lpAddress CODE:00402649 180 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+44h] CODE:0040264C 180 push eax ; hProcess CODE:0040264D 184 call VirtualProtectEx CODE:0040264D CODE:00402652 CODE:00402652 err_writeprocmem: ; CODE XREF: launch_image_in_memory+1ACj CODE:00402652 170 inc ebx ; next section CODE:00402653 170 dec dword ptr [ebp+hProcess.ExtendedRegisters+54h] CODE:00402656 170 jnz short insert_section_into_process_space CODE:00402656 CODE:00402658 CODE:00402658 ; the loader exploits the fact that ebx points CODE:00402658 ; to the PEB at process start. CODE:00402658 ; so by patching the DWORD pointed to by ebx+8, CODE:00402658 ; the loader sets a new ImageBaseAddress within CODE:00402658 ; the PEB structure CODE:00402658 ; (http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/PEB.html) CODE:00402658 CODE:00402658 CODE:00402658 err_no_more_sections: ; CODE XREF: launch_image_in_memory+17Dj CODE:00402658 170 lea eax, [ebp+hProcess.ExtendedRegisters+64h] CODE:0040265B 170 push eax ; lpNumberOfBytesWritten CODE:0040265C 174 push 4 ; nSize CODE:0040265E 178 lea eax, [ebp+hProcess.ExtendedRegisters+6Ch] CODE:00402661 178 push eax ; lpBuffer CODE:00402662 17C mov eax, [ebp+hProcess._Ebx] CODE:00402668 17C add eax, 8 CODE:0040266B 17C push eax ; lpBaseAddress CODE:0040266C 180 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+44h] CODE:0040266F 180 push eax ; hProcess CODE:00402670 184 call WriteProcessMemory CODE:00402670 CODE:00402675 170 test eax, eax CODE:00402677 170 jz short err_ldrfailure CODE:00402677 CODE:00402679 CODE:00402679 ; get AddressOfEntrypoint, add address of image CODE:00402679 ; in memory and set eax of the target process to CODE:00402679 ; that address CODE:00402679 CODE:00402679 170 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+5Ch] ; PE header CODE:0040267C 170 mov eax, [eax+28h] ; PE header + 0x28 = address of entrypoint CODE:0040267F 170 add eax, dword ptr [ebp+hProcess.ExtendedRegisters+6Ch] CODE:00402682 170 mov [ebp+hProcess._Eax], eax CODE:00402688 170 lea eax, [ebp+hProcess] CODE:0040268E 170 push eax ; lpContext CODE:0040268F 174 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+48h] CODE:00402692 174 push eax ; hThread CODE:00402693 178 call SetThreadContext CODE:00402693 CODE:00402698 170 cmp eax, 1 CODE:0040269B 170 sbb eax, eax CODE:0040269D 170 inc eax CODE:0040269E 170 mov [ebp+hProcess.ExtendedRegisters+5Bh], al CODE:0040269E CODE:004026A1 CODE:004026A1 err_ldrfailure: ; CODE XREF: launch_image_in_memory+C4j CODE:004026A1 ; launch_image_in_memory+E9j ... CODE:004026A1 170 xor eax, eax CODE:004026A3 170 pop edx CODE:004026A4 16C pop ecx CODE:004026A5 168 pop ecx CODE:004026A6 164 mov fs:[eax], edx CODE:004026A9 164 push offset err_createproc CODE:004026A9 CODE:004026AE CODE:004026AE loc_4026AE: ; CODE XREF: launch_image_in_memory+253j CODE:004026AE 168 cmp [ebp+hProcess.ExtendedRegisters+5Bh], 0 CODE:004026B2 168 jnz short resume_process CODE:004026B2 CODE:004026B4 CODE:004026B4 ; on failure, terminate process CODE:004026B4 CODE:004026B4 168 push 0 ; uExitCode CODE:004026B6 16C mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+44h] CODE:004026B9 16C push eax ; hProcess CODE:004026BA 170 call TerminateProcess CODE:004026BA CODE:004026BF 168 jmp short loc_4026CA CODE:004026BF CODE:004026C1 ; --------------------------------------------------------------------------- CODE:004026C1 CODE:004026C1 resume_process: ; CODE XREF: launch_image_in_memory+232j CODE:004026C1 168 mov eax, dword ptr [ebp+hProcess.ExtendedRegisters+48h] CODE:004026C4 168 push eax ; hThread CODE:004026C5 16C call ResumeThread CODE:004026C5 CODE:004026CA CODE:004026CA loc_4026CA: ; CODE XREF: launch_image_in_memory+23Fj CODE:004026CA 168 mov bl, [ebp+hProcess.ExtendedRegisters+5Bh] CODE:004026CD 168 retn CODE:004026CD CODE:004026CE ; --------------------------------------------------------------------------- CODE:004026CE CODE:004026CE loc_4026CE: ; DATA XREF: launch_image_in_memory+9Do CODE:004026CE 164 jmp loc_401A3C CODE:004026CE CODE:004026D3 ; --------------------------------------------------------------------------- CODE:004026D3 164 jmp short loc_4026AE CODE:004026D3 CODE:004026D5 ; --------------------------------------------------------------------------- CODE:004026D5 CODE:004026D5 err_createproc: ; CODE XREF: launch_image_in_memory+90j CODE:004026D5 ; launch_image_in_memory+24Dj CODE:004026D5 ; DATA XREF: ... CODE:004026D5 164 xor eax, eax CODE:004026D7 164 pop edx CODE:004026D8 160 pop ecx CODE:004026D9 15C pop ecx CODE:004026DA 158 mov fs:[eax], edx CODE:004026DD 158 push offset loc_4026F7 CODE:004026DD CODE:004026E2 CODE:004026E2 loc_4026E2: ; CODE XREF: launch_image_in_memory+275j CODE:004026E2 15C lea eax, [ebp+hProcess.ExtendedRegisters+70h] CODE:004026E5 15C mov edx, 2 CODE:004026EA 15C call sub_401C90 CODE:004026EA CODE:004026EF 15C retn CODE:004026EF CODE:004026F0 ; --------------------------------------------------------------------------- CODE:004026F0 CODE:004026F0 loc_4026F0: ; DATA XREF: launch_image_in_memory+28o CODE:004026F0 158 jmp loc_401A3C CODE:004026F0 CODE:004026F5 ; --------------------------------------------------------------------------- CODE:004026F5 158 jmp short loc_4026E2 CODE:004026F5 CODE:004026F7 ; --------------------------------------------------------------------------- CODE:004026F7 CODE:004026F7 loc_4026F7: ; CODE XREF: launch_image_in_memory+26Fj CODE:004026F7 ; DATA XREF: launch_image_in_memory+25Do CODE:004026F7 15C mov eax, ebx CODE:004026F9 15C pop edi CODE:004026FA 158 pop esi CODE:004026FB 154 pop ebx CODE:004026FC 150 mov esp, ebp CODE:004026FE 008 pop ebp CODE:004026FF 004 retn 4 CODE:004026FF CODE:004026FF launch_image_in_memory endp ; sp-analysis failed CODE:004026FF CODE:004026FF ; ---------------------------------------------------------------------------