Guest User

Untitled

a guest
Sep 8th, 2018
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.34 KB | None | 0 0
  1. // Modified by Zoltan Csizmadia, zoltan_csizmadia@yahoo.com
  2. // For companies(Austin,TX): If you would like to get my resume, send an email.
  3. //
  4. //******************************************************************************
  5. //
  6. // Original version made by Felix Kasza, http://www.mvps.org/win32/
  7. //
  8. // demonstrates getting the command line of another process
  9. // requires PROCESS_CREATE_THREAD, PROCESS_VM_OPERATION,
  10. // PROCESS_VM_WRITE, PROCESS_VM_READ to the target, or the
  11. // SeDebugPrivilege
  12.  
  13. // *** You *must* remove "/GZ" from the debug build settings ***
  14. // (If you use my (felixk's) project file, this has already happened)
  15.  
  16. #include <windows.h>
  17. #include <stdio.h>
  18.  
  19. const DWORD MAXINJECTSIZE = 4096;
  20.  
  21. typedef HMODULE (__stdcall *PLoadLibraryW)(wchar_t*);
  22. typedef HMODULE (__stdcall *PGetModuleHandleW)(wchar_t*);
  23. typedef BOOL    (__stdcall *PFreeLibrary)(HMODULE);
  24. typedef FARPROC (__stdcall *PGetProcAddress)(HMODULE, char*);
  25.  
  26. struct RemoteThreadBlock
  27. {
  28.     DWORD               ErrorLoad;                  // error value for LoadLibrary
  29.     DWORD               ErrorFunction;              // error value for executed function
  30.     DWORD               ReturnCodeForFunction;      // error value for executed function
  31.     DWORD               ErrorFree;                  // error value for FreeLibrary
  32.  
  33.     HMODULE             hModule;
  34.     BOOL                bLoadLibrary;
  35.     BOOL                bFreeLibrary;
  36.  
  37.     PLoadLibraryW       fnLoadLibrary;
  38.     PGetModuleHandleW   fnGetModuleHandle;
  39.     PFreeLibrary        fnFreeLibrary;
  40.     PGetProcAddress     fnGetProcAddress;
  41.  
  42.     wchar_t             lpModulePath[_MAX_PATH];    // the DLL path
  43.     char                lpFunctionName[256];        // the called function
  44. };
  45.  
  46. // convert wchar* to char*
  47. DWORD ConvertWCharToChar( wchar_t*, char*, DWORD );
  48.  
  49. // try to enable SeDebugPrivilege
  50. void EnableDebugPriv( void );
  51.  
  52. // inject function RemoteThread() into target process
  53. bool ExecuteRemoteThread( HANDLE, BOOL, BOOL, wchar_t*, wchar_t* );
  54.  
  55. // and this is the code we are injecting
  56. DWORD __stdcall RemoteThread( RemoteThreadBlock* );
  57.  
  58. // "main" function
  59. DWORD LoadDllForRemoteThread( DWORD, BOOL, BOOL, wchar_t*, wchar_t* );
  60.  
  61. // check OS
  62. BOOL IsWindowsNT();
  63.  
  64. int wmain( int argc, wchar_t *argv[] )
  65. {
  66.     BOOL bUsage = TRUE;
  67.  
  68.     DWORD pID = 0;
  69.     wchar_t* lpModulePath = NULL;
  70.     wchar_t* lpFunctionName = NULL;
  71.     BOOL bLoad = FALSE;
  72.     BOOL bFree = FALSE;
  73.  
  74.     // check the parameters
  75.     for ( int i = 1, j = 0 ; i < argc; i++ )
  76.     {
  77.         if ( wcsicmp( argv[i], L"/?" ) == 0 || wcsicmp( argv[i], L"-?" ) == 0 ||
  78.              wcsicmp( argv[i], L"/h" ) == 0 || wcsicmp( argv[i], L"-h" ) == 0 ||
  79.              wcsicmp( argv[i], L"/help" ) == 0 || wcsicmp( argv[i], L"-help" ) == 0 )
  80.         {
  81.             // help
  82.             bUsage = TRUE;
  83.             break;
  84.         }
  85.         else
  86.         if ( wcsicmp( argv[i], L"/l" ) == 0 || wcsicmp( argv[i], L"-l" ) == 0 )
  87.         {
  88.             // load the library
  89.             bLoad = TRUE;
  90.         }
  91.         else
  92.         if ( wcsicmp( argv[i], L"/u" ) == 0 || wcsicmp( argv[i], L"-u" ) == 0 )
  93.         {
  94.             // unload the library
  95.             bFree = TRUE;
  96.         }
  97.         else
  98.         {
  99.             switch ( j )
  100.             {
  101.             case 0:
  102.                 // first parameter is the process ID
  103.                 {
  104.                     char strPId[10];
  105.  
  106.                     //Get process ID
  107.                     ConvertWCharToChar( argv[i], strPId, sizeof(strPId) );
  108.                     pID = atoi( strPId );
  109.  
  110.                     if ( pID == -1 )
  111.                         pID = GetCurrentProcessId();
  112.                 }
  113.                 break;
  114.  
  115.             case 1:
  116.                 // second parameter is the dll path
  117.                 lpModulePath = argv[i];
  118.  
  119.                 // we need at least the pId and dllPath
  120.                 bUsage = FALSE;
  121.                 break;
  122.  
  123.             case 2:
  124.                 // thirs parameter is the function ( this is optional )
  125.                 lpFunctionName = argv[i];
  126.                 break;
  127.  
  128.             default:
  129.                 //too many parameters, let's show the help
  130.                 break;
  131.             };
  132.  
  133.             j++;
  134.         }
  135.     };
  136.  
  137.     if ( bUsage )
  138.     {
  139.         //Usage information
  140.         wprintf( L"LOADDLL 1.0 for WinNT/Win2k  Loads a DLL into a remote process\n" );
  141.         wprintf( L"\n" );
  142.         wprintf( L"Written by Zoltan Csizmadia, zoltan_csizmadia@yahoo.com\n" );
  143.         wprintf( L"Based on Felix Kasza's CreateRemoteThread exmample, www.mvps.org\\win32\n" );
  144.         wprintf( L"\n" );
  145.         wprintf( L"Usage: LOADDLL [/L] [/U] processID dllPath [functionName]\n" );
  146.         wprintf( L"\n" );
  147.         wprintf( L"          /L              Loads the module\n" );
  148.         wprintf( L"          /U              Unloads the module\n" );
  149.         wprintf( L"\n" );
  150.         wprintf( L"          processID       Process ID\n" );
  151.         wprintf( L"          dllPath         Path for the module\n" );
  152.         wprintf( L"          functionName    Called function. Mustn't have parameters\n" );
  153.         wprintf( L"\n" );
  154.         wprintf( L"Examples:\n" );
  155.         wprintf( L"          Loads and then unloads the module for process #728\n" );
  156.         wprintf( L"          LOADDLL /L /U 728 your.dll\n" );
  157.         wprintf( L"\n" );
  158.         wprintf( L"          Loads, calls the fnTest and unloads the module for process #728\n" );
  159.         wprintf( L"          LOADDLL /L /U 728 your.dll fnTest\n" );
  160.         wprintf( L"\n" );
  161.         wprintf( L"          Call the fnTest function. The module has to be loaded to the process\n" );
  162.         wprintf( L"          LOADDLL 728 your.dll fnTest\n" );
  163.         wprintf( L"\n" );
  164.         wprintf( L"          Unload the \"your.dll\" from process #728\n" );
  165.         wprintf( L"          LOADDLL /U 728 your.dll\n" );
  166.         wprintf( L"\n" );
  167.         wprintf( L"          Breaks the remote process\n" );
  168.         wprintf( L"          LOADDLL 728 kernel32.dll DebugBreak\n" );
  169.        
  170.         return 1;
  171.     }
  172.  
  173.     // we need WinNT/Win2k
  174.     if ( !IsWindowsNT() )
  175.     {
  176.         wprintf( L"This executable needs WindowsNT/Windows2000\n" );
  177.         return 2;
  178.     }
  179.  
  180.     //Enable debug privilege
  181.     EnableDebugPriv();
  182.  
  183.     //Let's work
  184.     LoadDllForRemoteThread( pID, bLoad, bFree, lpModulePath, lpFunctionName );
  185.    
  186.     return 0;
  187. }
  188.  
  189. BOOL IsWindowsNT()
  190. {
  191.    OSVERSIONINFOEX osvi;
  192.    BOOL bOsVersionInfoEx;
  193.    
  194.    // Try calling GetVersionEx using the OSVERSIONINFOEX structure,
  195.    // which is supported on Windows 2000.
  196.    //
  197.    // If that fails, try using the OSVERSIONINFO structure.
  198.  
  199.    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  200.    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  201.  
  202.    bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi);
  203.  
  204.    if( bOsVersionInfoEx == 0 )
  205.    {
  206.       // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
  207.  
  208.       osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
  209.       if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
  210.          return FALSE;
  211.    }
  212.  
  213.    return osvi.dwPlatformId == VER_PLATFORM_WIN32_NT;
  214. }
  215.  
  216. DWORD ConvertWCharToChar( wchar_t* wStr, char* cStr, DWORD size )
  217. {
  218.     ULONG i = 0;
  219.     wchar_t* wAct = wStr;
  220.     char* cAct = cStr;
  221.  
  222.     *cStr = 0;
  223.  
  224.     while ( *wAct != 0 && i < size )
  225.     {
  226.         *cAct++ = (char)*wAct++;
  227.         i++;
  228.     }
  229.  
  230.     return i;
  231. }
  232.  
  233. DWORD LoadDllForRemoteThread( DWORD processID, BOOL bLoad, BOOL bFree, wchar_t* lpModuleName, wchar_t* lpFunctionName )
  234. {
  235.     // open the process
  236.     HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
  237.             PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, processID );
  238.    
  239.     if ( hProcess != NULL )
  240.     {
  241.         // let's work
  242.         ExecuteRemoteThread( hProcess, bLoad, bFree, lpModuleName, lpFunctionName );
  243.  
  244.         CloseHandle( hProcess );
  245.     }
  246.     else
  247.         wprintf( L"Open remote process failed! Error = %d\n", GetLastError() );
  248.        
  249.     return 0;
  250. }
  251.  
  252. void EnableDebugPriv( void )
  253. {
  254.     HANDLE hToken;
  255.     LUID sedebugnameValue;
  256.     TOKEN_PRIVILEGES tkp;
  257.  
  258.     // enable the SeDebugPrivilege
  259.     if ( ! OpenProcessToken( GetCurrentProcess(),
  260.         TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
  261.     {
  262.         wprintf( L"OpenProcessToken() failed, Error = %d SeDebugPrivilege is not available.\n", GetLastError() );
  263.         return;
  264.     }
  265.  
  266.     if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) )
  267.     {
  268.         wprintf( L"LookupPrivilegeValue() failed, Error = %d SeDebugPrivilege is not available.\n", GetLastError() );
  269.         CloseHandle( hToken );
  270.         return;
  271.     }
  272.  
  273.     tkp.PrivilegeCount = 1;
  274.     tkp.Privileges[0].Luid = sedebugnameValue;
  275.     tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  276.  
  277.     if ( ! AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) )
  278.         wprintf( L"AdjustTokenPrivileges() failed, Error = %d SeDebugPrivilege is not available.\n", GetLastError() );
  279.        
  280.     CloseHandle( hToken );
  281. }
  282.  
  283. bool ExecuteRemoteThread( HANDLE hProcess, BOOL bLoad, BOOL bFree, wchar_t* lpDllPath, wchar_t* lpFunctionName )
  284. {
  285.     HANDLE ht = 0;
  286.     void *p = 0;
  287.     RemoteThreadBlock *c = 0;
  288.     bool result = false;
  289.     DWORD rc;
  290.     HMODULE hKernel32 = 0;
  291.     RemoteThreadBlock localCopy;
  292.  
  293.     // clear the parameter block
  294.     ::ZeroMemory( &localCopy, sizeof(localCopy) );
  295.  
  296.     // allocate memory for injected code
  297.     p = VirtualAllocEx( hProcess, 0, MAXINJECTSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
  298.     if ( p == 0 )
  299.     {
  300.         wprintf( L"VirtualAllocEx() failed, Error = %d \n", GetLastError() );
  301.         goto cleanup;
  302.     }
  303.  
  304.     // allocate memory for parameter block
  305.     c = (RemoteThreadBlock*) VirtualAllocEx( hProcess, 0, sizeof(RemoteThreadBlock), MEM_COMMIT, PAGE_READWRITE );
  306.     if ( c == 0 )
  307.     {
  308.         wprintf( L"VirtualAllocEx() failed, Error = %d \n", GetLastError() );
  309.         goto cleanup;
  310.     }
  311.  
  312.     // copy function there, we will execute this piece of code
  313.     if ( ! WriteProcessMemory( hProcess, p, NULL, 0, 0 ) )
  314.     {
  315.         wprintf( L"WriteProcessMemory() failed, Error = %d \n", GetLastError() );
  316.         goto cleanup;
  317.     }
  318.  
  319.    
  320.     // copy dll path to parameter block
  321.     wcscpy( localCopy.lpModulePath, lpDllPath );
  322.  
  323.     //GetProcAddrees doesn't support UNICODE ?!?!
  324.     if ( lpFunctionName == NULL )
  325.         localCopy.lpFunctionName[0] = 0;
  326.     else
  327.         ConvertWCharToChar( lpFunctionName, localCopy.lpFunctionName, sizeof(localCopy.lpFunctionName) );
  328.    
  329.     localCopy.bLoadLibrary = bLoad;
  330.     localCopy.bFreeLibrary = bFree;
  331.  
  332.     // load kernel32.dll
  333.     hKernel32 = LoadLibrary( "kernel32.dll" );
  334.  
  335.     if ( hKernel32 == NULL )
  336.     {
  337.         wprintf( L"Couldn't load kernel32.dll. That's a surprise!\n" );
  338.         goto cleanup;
  339.     }
  340.  
  341.     // get the addresses for the functions, what we will use in the remote thread
  342.     localCopy.fnLoadLibrary = (PLoadLibraryW)GetProcAddress( hKernel32, "LoadLibraryW" );
  343.     localCopy.fnGetModuleHandle = (PGetModuleHandleW)GetProcAddress( hKernel32, "GetModuleHandleW" );
  344.     localCopy.fnFreeLibrary = (PFreeLibrary)GetProcAddress( hKernel32, "FreeLibrary" );
  345.     localCopy.fnGetProcAddress = (PGetProcAddress)GetProcAddress( hKernel32, "GetProcAddress" );
  346.  
  347.     if (localCopy.fnLoadLibrary == NULL ||
  348.         localCopy.fnGetModuleHandle == NULL ||
  349.         localCopy.fnFreeLibrary == NULL ||
  350.         localCopy.fnGetProcAddress == NULL)
  351.     {
  352.         wprintf( L"GetProcAddress() failed. Error = %d\n", GetLastError() );
  353.         goto cleanup;
  354.     }
  355.  
  356.    
  357.     // copy the parameterblock to the other process adress space
  358.     if ( ! WriteProcessMemory( hProcess, c, &localCopy, sizeof localCopy, 0 ) )
  359.     {
  360.         wprintf( L"WriteProcessMemory() failed, Error = %d \n", GetLastError() );
  361.         goto cleanup;
  362.     }
  363.  
  364.     // CreateRemoteThread()
  365.     ht = CreateRemoteThread( hProcess, 0, 0, (DWORD (__stdcall *)( void *)) p, c, 0, &rc );
  366.     if ( ht == NULL )
  367.     {
  368.         wprintf( L"CreateRemoteThread() failed, Error = %d \n", GetLastError() );
  369.         goto cleanup;
  370.     }
  371.  
  372.     rc = WaitForSingleObject( ht, INFINITE );
  373.     switch ( rc )
  374.     {
  375.     case WAIT_TIMEOUT:
  376.         wprintf( L"WaitForSingleObject() timed out. INFINITE is over!" );
  377.         goto cleanup;
  378.     case WAIT_FAILED:
  379.         wprintf( L"WaitForSingleObject() failed, Error = %d \n", GetLastError() );
  380.         goto cleanup;
  381.     case WAIT_OBJECT_0:
  382.         // this might just have worked, pick up the result!
  383.         // rad back the prameter block, it has the error code
  384.         if ( ! ReadProcessMemory( hProcess, c, &localCopy, sizeof localCopy, 0 ) )
  385.         {
  386.             wprintf( L"ReadProcessMemory() failed, Error = %d\n", GetLastError() );
  387.             goto cleanup;
  388.         }
  389.  
  390.         // get the result about loading the library
  391.         if ( bLoad )
  392.         {
  393.             wprintf( L"Loading \"%s\": ", lpDllPath );
  394.             switch( localCopy.ErrorLoad )
  395.             {
  396.             case 0:
  397.                 wprintf( L"Loaded (0x%08X)\n", localCopy.hModule );
  398.                 break;
  399.  
  400.             default:
  401.                 wprintf( L"Couldn't load\n", localCopy.ErrorLoad );
  402.                 break;
  403.             }
  404.         }
  405.  
  406.         // get the result about loading the library
  407.         if ( lpFunctionName != NULL )
  408.         {
  409.             wprintf( L"Calling \"%s\": ", lpFunctionName );
  410.  
  411.             switch( localCopy.ErrorFunction )
  412.             {
  413.             case 0:
  414.                 wprintf( L"Executed (0x%X)\n", localCopy.ReturnCodeForFunction );
  415.                 break;
  416.  
  417.             default:
  418.                 wprintf( L"Couldn't find\n" );
  419.                 break;
  420.             }
  421.         }
  422.                
  423.         // get the result about freeing the library
  424.         if ( bFree )
  425.         {
  426.             wprintf( L"Freeing \"%s\": ", lpDllPath );
  427.             switch( localCopy.ErrorFree )
  428.             {
  429.             case 0:
  430.                 wprintf( L"Released (0x%08X)\n", localCopy.hModule );
  431.                 break;
  432.  
  433.             default:
  434.                 wprintf( L"Couldn't free\n" );
  435.                 break;
  436.             }
  437.         }
  438.        
  439.         break;
  440.    
  441.     default:
  442.         wprintf( L"WaitForSingleObject() failed, Error = %d \n", GetLastError() );
  443.         break;
  444.     }
  445.  
  446. cleanup:
  447.     CloseHandle( ht );
  448.  
  449.     // Let's clean
  450.     if ( p != 0 )
  451.         VirtualFreeEx( hProcess, p, 0, MEM_RELEASE );
  452.     if ( c != 0 )
  453.         VirtualFreeEx( hProcess, c, 0, MEM_RELEASE );
  454.     if ( hKernel32 != NULL)
  455.         FreeLibrary( hKernel32 );
  456.  
  457.     return result;
  458. }
  459.  
  460.  
  461. // The whole shebang makes a number of assumptions:
  462. // -- target process is a Win32 process
  463. // -- kernel32.dll loaded at same address in each process (safe)
  464. // -- bem() shorter than MAXINJECTSIZE
  465. // -- bem() does not rely on the C/C++ runtime
  466. // -- /GZ is _not_ used. (If it is, the compiler generates calls
  467. //    to functions which are not injected into the target. Oops!
  468. DWORD __stdcall RemoteThread( RemoteThreadBlock* execBlock )
  469. {
  470.     // and this is the code we are injecting
  471.  
  472.     typedef DWORD (*PRemoteDllFunction)();
  473.  
  474.     HMODULE hModule = NULL;
  475.  
  476.     // clear the error codes
  477.     execBlock->ErrorLoad = 0;
  478.     execBlock->ErrorFunction = 0;
  479.     execBlock->ErrorFree = 0;
  480.  
  481.     // load the requested dll
  482.     if ( execBlock->bLoadLibrary )
  483.     {
  484.         execBlock->hModule = (HMODULE)(*execBlock->fnLoadLibrary)( execBlock->lpModulePath );
  485.  
  486.         hModule = execBlock->hModule;
  487.  
  488.         execBlock->ErrorLoad = execBlock->hModule != NULL ? 0 : 1;
  489.     }
  490.  
  491.     // if we didn't load the library, try to query the module handle
  492.     if ( hModule == NULL )
  493.         hModule = (*execBlock->fnGetModuleHandle)( execBlock->lpModulePath );
  494.  
  495.     // call function
  496.     if ( execBlock->lpFunctionName[0] != 0 )
  497.     {
  498.         //execute a function if we have a function name
  499.         PRemoteDllFunction fnRemoteDllFunction = (PRemoteDllFunction)
  500.             (*execBlock->fnGetProcAddress)( hModule, execBlock->lpFunctionName );
  501.  
  502.         // execute the function, and get the result
  503.         if ( fnRemoteDllFunction != NULL )
  504.         {
  505.             execBlock->ErrorFunction = 0;
  506.             execBlock->ReturnCodeForFunction = (*fnRemoteDllFunction)();
  507.         }
  508.         else
  509.             execBlock->ErrorFunction = 1;
  510.     }
  511.  
  512.     // free library
  513.     if ( execBlock->bFreeLibrary )
  514.     {
  515.         execBlock->ErrorFree = execBlock->fnFreeLibrary( hModule ) ? 0 : 1;
  516.     }
  517.  
  518.     execBlock->hModule = hModule;
  519.    
  520.     return 0;
  521. }
Add Comment
Please, Sign In to add comment