├── .gitignore ├── LICENSE ├── README.md ├── RunWithDll.c └── asm ├── amd64.asm └── i386.asm /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.out 25 | *.app 26 | *.i*86 27 | *.x86_64 28 | *.hex 29 | 30 | # Debug files 31 | *.dSYM/ 32 | *.su 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 root@tinysec.net 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # runwithdll 2 | windows create process with a dll load first time 3 | 4 | 5 | sample 6 | 7 | ```c 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | LONG RunWithDllW(__in WCHAR* pszApplication , __in_opt WCHAR* pszCommandline , __in WCHAR* pszTargetDll , __in ULONG nWaitTime ); 15 | 16 | 17 | int __cdecl wmain(int nArgc, WCHAR** ppArgv) 18 | { 19 | LONG nRet = -1; 20 | 21 | WCHAR* pszCommandline = NULL; 22 | WCHAR* pszLeftCommandline = NULL; 23 | ULONG nCommandlineLen = 0; 24 | ULONG nDataLen = 0; 25 | int nIndex = 0; 26 | 27 | do 28 | { 29 | if ( nArgc < 3 ) 30 | { 31 | wprintf( L"Run Process With Dll via LdrHook \n\n"); 32 | 33 | wprintf( L"Usage:\n"); 34 | wprintf( L"RunWithDll.exe {Application} {TargetDll} [Commandline]\n" ); 35 | 36 | wprintf( L"\n"); 37 | 38 | wprintf( L"Sample:\n"); 39 | wprintf( L"RunWithDll.exe c:\\windows\\notepad.exe d:\\hook.dll\n" ); 40 | wprintf( L"RunWithDll.exe c:\\windows\\notepad.exe d:\\hook.dll c:\\windows\\win.ini \n" ); 41 | break; 42 | } 43 | 44 | if ( nArgc > 3 ) 45 | { 46 | for ( nIndex = 3; nIndex < nArgc; nIndex++ ) 47 | { 48 | nCommandlineLen += (ULONG)wcslen( ppArgv[nIndex] ) + 3; 49 | } 50 | 51 | nCommandlineLen += 1; 52 | 53 | pszLeftCommandline = (WCHAR*)malloc( nCommandlineLen * sizeof(WCHAR) ); 54 | if ( NULL == pszLeftCommandline ) 55 | { 56 | break; 57 | } 58 | RtlZeroMemory( pszLeftCommandline , nCommandlineLen * sizeof(WCHAR) ); 59 | 60 | for ( nIndex = 3; nIndex < nArgc; nIndex++ ) 61 | { 62 | if ( L'"' != ppArgv[nIndex][0] ) 63 | { 64 | wcsncpy( pszLeftCommandline + nDataLen , L"\"" , 1 ); 65 | nDataLen += 1; 66 | } 67 | 68 | wcsncpy( pszLeftCommandline + nDataLen , ppArgv[nIndex] , wcslen( ppArgv[nIndex] ) ); 69 | nDataLen += wcslen( ppArgv[nIndex] ); 70 | 71 | if ( L'"' != ppArgv[nIndex][0] ) 72 | { 73 | wcsncpy( pszLeftCommandline + nDataLen , L"\"" , 1 ); 74 | nDataLen += 1; 75 | } 76 | } 77 | 78 | pszCommandline = pszLeftCommandline; 79 | } 80 | 81 | RunWithDllW( ppArgv[1] , pszCommandline , ppArgv[2] , 0); 82 | 83 | } while (FALSE); 84 | 85 | if ( NULL != pszLeftCommandline ) 86 | { 87 | free( pszLeftCommandline ); 88 | pszLeftCommandline = NULL; 89 | } 90 | 91 | return 0; 92 | } 93 | 94 | 95 | ``` -------------------------------------------------------------------------------- /RunWithDll.c: -------------------------------------------------------------------------------- 1 | // windows create process with dll loaded at first time. 2 | // by TinySec( root@tinysec.net ) 3 | // you can free use this code , but if you had modify , send a copy to to my email please. 4 | 5 | 6 | 7 | #include 8 | #include 9 | 10 | 11 | ////////////////////////////////////////////////////////////////////////// 12 | ULONG_PTR _RunWithDll_ALIGN_DOWN_BY( ULONG_PTR nLength , ULONG_PTR nAlign ) 13 | { 14 | return nLength & ~(nAlign - 1); 15 | } 16 | 17 | ULONG_PTR _RunWithDll_ALIGN_UP_BY( ULONG_PTR nLength , ULONG_PTR nAlign ) 18 | { 19 | return _RunWithDll_ALIGN_DOWN_BY( ((ULONG_PTR)(nLength) + nAlign - 1), nAlign ); 20 | } 21 | 22 | LONG _RunWithDll_GetTargetArchitecture(__in HANDLE hTargetProcess , __out WORD* pwArchitecture) 23 | { 24 | typedef BOOL (WINAPI *LPFN_IsWow64Process)( __in HANDLE hProcess, __out PBOOL Wow64Process); 25 | typedef VOID (WINAPI *LPFN_GetNativeSystemInfo)( __out LPSYSTEM_INFO lpSystemInfo ); 26 | 27 | LONG FinalStatus = -1; 28 | SYSTEM_INFO stSysInfo = {0}; 29 | HMODULE hKernel32 = NULL; 30 | 31 | LPFN_IsWow64Process fnIsWow64Process = NULL; 32 | LPFN_GetNativeSystemInfo fnGetNativeSystemInfo = NULL; 33 | BOOL bFlag = FALSE; 34 | BOOL bWow64 = FALSE; 35 | 36 | WORD wProcessorArchitecture = 0; 37 | 38 | 39 | 40 | do 41 | { 42 | if (NULL == pwArchitecture) 43 | { 44 | break; 45 | } 46 | 47 | hKernel32 = GetModuleHandleA("kernel32.dll"); 48 | if (NULL == hKernel32) 49 | { 50 | break; 51 | } 52 | 53 | fnIsWow64Process = (LPFN_IsWow64Process)GetProcAddress(hKernel32, "IsWow64Process"); 54 | if (NULL == fnIsWow64Process) 55 | { 56 | break; 57 | } 58 | 59 | fnGetNativeSystemInfo = (LPFN_GetNativeSystemInfo)GetProcAddress(hKernel32, "GetNativeSystemInfo"); 60 | if (NULL == fnGetNativeSystemInfo) 61 | { 62 | break; 63 | } 64 | 65 | fnGetNativeSystemInfo(&stSysInfo); 66 | 67 | if (PROCESSOR_ARCHITECTURE_AMD64 == stSysInfo.wProcessorArchitecture) 68 | { 69 | bFlag = fnIsWow64Process(hTargetProcess , &bWow64); 70 | 71 | if (bWow64) 72 | { 73 | wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL; 74 | } 75 | else 76 | { 77 | wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; 78 | } 79 | 80 | 81 | 82 | FinalStatus = 0; 83 | } 84 | else if (PROCESSOR_ARCHITECTURE_INTEL == stSysInfo.wProcessorArchitecture) 85 | { 86 | wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL; 87 | 88 | FinalStatus = 0; 89 | } 90 | else 91 | { 92 | FinalStatus = -2; 93 | } 94 | 95 | } while (FALSE); 96 | 97 | if (NULL != pwArchitecture) 98 | { 99 | *pwArchitecture = wProcessorArchitecture; 100 | } 101 | 102 | return FinalStatus; 103 | } 104 | 105 | 106 | LONG _RunWithDll_RemoteGetNtdllImageBase(__in HANDLE hTargetProcess , __in BOOL bTarget64, __out void** ppTargetNtdllImageBase) 107 | { 108 | LONG FinalStatus = -1; 109 | ULONG_PTR ulRet = 0; 110 | BOOL bFlag = FALSE; 111 | 112 | void* RemoteAddress = NULL; 113 | ULONG64 ulValue = 0; 114 | ULONG_PTR ulBytesRead = 0; 115 | 116 | IMAGE_NT_HEADERS32* pNtHeader32 = NULL; 117 | IMAGE_EXPORT_DIRECTORY* pExportDir = NULL; 118 | 119 | ULONG FindAddress = 0; 120 | 121 | MEMORY_BASIC_INFORMATION stMemBasicInfo = {0}; 122 | ULONG ulRegionSize = 0; 123 | 124 | char* pszDllName = NULL; 125 | 126 | 127 | do 128 | { 129 | if ( NULL == ppTargetNtdllImageBase) 130 | { 131 | break; 132 | } 133 | 134 | #ifdef _WIN64 135 | if (bTarget64) 136 | { 137 | *ppTargetNtdllImageBase = GetModuleHandleA("ntdll.dll"); 138 | FinalStatus = 0; 139 | break; 140 | } 141 | #else 142 | if (!bTarget64) 143 | { 144 | *ppTargetNtdllImageBase = GetModuleHandleA("ntdll.dll"); 145 | FinalStatus = 0; 146 | break; 147 | } 148 | else 149 | { 150 | FinalStatus = 0xC00000BBL; 151 | break; 152 | } 153 | #endif //_WIN64 154 | 155 | // need search , bTarget64 must false 156 | 157 | pszDllName = (CHAR*)malloc( MAX_PATH ); 158 | if (NULL == pszDllName) 159 | { 160 | break; 161 | } 162 | RtlZeroMemory(pszDllName, MAX_PATH); 163 | 164 | pNtHeader32 = (IMAGE_NT_HEADERS32*)malloc( sizeof(IMAGE_NT_HEADERS32) ); 165 | if (NULL == pNtHeader32) 166 | { 167 | break; 168 | } 169 | RtlZeroMemory(pNtHeader32, sizeof(IMAGE_NT_HEADERS32)); 170 | 171 | pExportDir = (IMAGE_EXPORT_DIRECTORY*)malloc( sizeof(IMAGE_EXPORT_DIRECTORY)); 172 | if (NULL == pExportDir) 173 | { 174 | break; 175 | } 176 | RtlZeroMemory(pExportDir , sizeof(IMAGE_EXPORT_DIRECTORY)); 177 | 178 | for (FindAddress = 0x10000; FindAddress < 0x7FFF0000; FindAddress += ulRegionSize) 179 | { 180 | RtlZeroMemory(&stMemBasicInfo, sizeof(stMemBasicInfo)); 181 | 182 | ulRet = VirtualQueryEx( 183 | hTargetProcess, 184 | (void*)FindAddress, 185 | &stMemBasicInfo, 186 | sizeof(stMemBasicInfo) 187 | ); 188 | 189 | if (0 == ulRet) 190 | { 191 | ulRegionSize = 0x10000; 192 | continue; 193 | } 194 | 195 | if ( ( MEM_COMMIT != (stMemBasicInfo.State & MEM_COMMIT) ) || (PAGE_NOACCESS == stMemBasicInfo.Protect) ) 196 | { 197 | ulRegionSize = (ULONG)_RunWithDll_ALIGN_UP_BY(stMemBasicInfo.RegionSize , 0x10000); 198 | continue; 199 | } 200 | 201 | 202 | //IMAGE_DOS_SIGNATURE 203 | ulValue = 0; 204 | 205 | bFlag = ReadProcessMemory(hTargetProcess, 206 | (void*)FindAddress, 207 | &ulValue, 208 | sizeof(WORD), 209 | &ulBytesRead 210 | ); 211 | if (!bFlag) 212 | { 213 | ulRegionSize = 0x10000; 214 | continue; 215 | } 216 | 217 | if (IMAGE_DOS_SIGNATURE != (WORD)ulValue ) 218 | { 219 | ulRegionSize = 0x10000; 220 | continue; 221 | } 222 | 223 | // e_flnew 224 | ulValue = 0; 225 | 226 | bFlag = ReadProcessMemory(hTargetProcess, 227 | (void*)( FindAddress + FIELD_OFFSET(IMAGE_DOS_HEADER,e_lfanew) ), 228 | &ulValue, 229 | sizeof(ULONG), 230 | &ulBytesRead 231 | ); 232 | if (!bFlag) 233 | { 234 | ulRegionSize = 0x10000; 235 | continue; 236 | } 237 | 238 | RtlZeroMemory(pNtHeader32, sizeof(IMAGE_NT_HEADERS32)); 239 | 240 | bFlag = ReadProcessMemory(hTargetProcess, 241 | (void*)( FindAddress + (USHORT)ulValue ), 242 | pNtHeader32, 243 | sizeof(IMAGE_NT_HEADERS32), 244 | &ulBytesRead 245 | ); 246 | if (!bFlag) 247 | { 248 | ulRegionSize = 0x10000; 249 | continue; 250 | } 251 | 252 | if (pNtHeader32->Signature != IMAGE_NT_SIGNATURE) 253 | { 254 | ulRegionSize = 0x10000; 255 | continue; 256 | } 257 | 258 | ulRegionSize = (ULONG)_RunWithDll_ALIGN_UP_BY( pNtHeader32->OptionalHeader.SizeOfImage , 0x10000); 259 | 260 | if ( IMAGE_FILE_DLL != (IMAGE_FILE_DLL & pNtHeader32->FileHeader.Characteristics) ) 261 | { 262 | continue; 263 | } 264 | 265 | if ( (0 == pNtHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) \ 266 | || (0 == pNtHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) 267 | ) 268 | { 269 | continue; 270 | } 271 | 272 | RtlZeroMemory(pExportDir , sizeof(IMAGE_EXPORT_DIRECTORY) ); 273 | 274 | RemoteAddress = (void*)( FindAddress + pNtHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress ); 275 | 276 | bFlag = ReadProcessMemory(hTargetProcess, 277 | RemoteAddress, 278 | pExportDir, 279 | sizeof(IMAGE_EXPORT_DIRECTORY), 280 | &ulBytesRead 281 | ); 282 | if (!bFlag) 283 | { 284 | continue; 285 | } 286 | 287 | if ( 0 == pExportDir->Name) 288 | { 289 | continue; 290 | } 291 | 292 | RtlZeroMemory(pszDllName, MAX_PATH); 293 | 294 | bFlag = ReadProcessMemory(hTargetProcess, 295 | (void*)(FindAddress + pExportDir->Name), 296 | pszDllName, 297 | MAX_PATH, 298 | &ulBytesRead 299 | ); 300 | if (!bFlag) 301 | { 302 | continue; 303 | } 304 | 305 | if ( 0 == _stricmp(pszDllName,"ntdll.dll") ) 306 | { 307 | *ppTargetNtdllImageBase = (void*)FindAddress; 308 | FinalStatus = 0; 309 | break; 310 | } 311 | } 312 | 313 | } while (FALSE); 314 | 315 | if (NULL != pNtHeader32) 316 | { 317 | free(pNtHeader32); 318 | pNtHeader32 = NULL; 319 | } 320 | 321 | if ( NULL != pExportDir) 322 | { 323 | free(pExportDir); 324 | pExportDir = NULL; 325 | } 326 | 327 | if ( NULL != pszDllName) 328 | { 329 | free(pszDllName); 330 | pszDllName = NULL; 331 | } 332 | 333 | return FinalStatus; 334 | } 335 | 336 | LONG _RunWithDll_RemoteGetProcAddress(__in HANDLE hTargetProcess , __in BOOL bTarget64 , __in void* ModuleImageBase , __in char* pszRoutineName , __out void** ppRoutineAddress) 337 | { 338 | LONG FinalStatus = -1; 339 | BOOL bFlag = FALSE; 340 | 341 | 342 | ULONG64 ulValue = 0; 343 | ULONG_PTR ulBytesRead = 0; 344 | 345 | void* RemoteAddress = NULL; 346 | 347 | IMAGE_NT_HEADERS64* pNtHeader64 = NULL; 348 | IMAGE_NT_HEADERS32* pNtHeader32 = NULL; 349 | IMAGE_EXPORT_DIRECTORY* pExportDir = NULL; 350 | ULONG i = 0; 351 | 352 | char* pszFindName = NULL; 353 | 354 | do 355 | { 356 | if ( (0 == ModuleImageBase) || (NULL == pszRoutineName) || (NULL == ppRoutineAddress) ) 357 | { 358 | break; 359 | } 360 | 361 | ulValue = 0; 362 | bFlag = ReadProcessMemory(hTargetProcess, 363 | (UCHAR*)ModuleImageBase + FIELD_OFFSET(IMAGE_DOS_HEADER ,e_lfanew), 364 | &ulValue, 365 | sizeof(WORD), 366 | &ulBytesRead 367 | ); 368 | if (!bFlag) 369 | { 370 | break; 371 | } 372 | 373 | pszFindName = (CHAR*)malloc( MAX_PATH); 374 | if (NULL == pszFindName) 375 | { 376 | break; 377 | } 378 | RtlZeroMemory(pszFindName, MAX_PATH); 379 | 380 | if (bTarget64) 381 | { 382 | pNtHeader64 = (IMAGE_NT_HEADERS64*)malloc( sizeof(IMAGE_NT_HEADERS64) ); 383 | if (NULL == pNtHeader64) 384 | { 385 | break; 386 | } 387 | RtlZeroMemory(pNtHeader64, sizeof(IMAGE_NT_HEADERS64)); 388 | 389 | bFlag = ReadProcessMemory(hTargetProcess, 390 | (UCHAR*)ModuleImageBase + (USHORT)ulValue, 391 | pNtHeader64, 392 | sizeof(IMAGE_NT_HEADERS64), 393 | &ulBytesRead 394 | ); 395 | if (!bFlag) 396 | { 397 | break; 398 | } 399 | 400 | if ( (0 == pNtHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) \ 401 | || (0 == pNtHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) 402 | ) 403 | { 404 | break; 405 | } 406 | 407 | RemoteAddress = (UCHAR*)ModuleImageBase + pNtHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; 408 | } 409 | else 410 | { 411 | pNtHeader32 = (IMAGE_NT_HEADERS32*)malloc( sizeof(IMAGE_NT_HEADERS32)); 412 | if (NULL == pNtHeader32) 413 | { 414 | break; 415 | } 416 | RtlZeroMemory(pNtHeader32, sizeof(IMAGE_NT_HEADERS32)); 417 | 418 | bFlag = ReadProcessMemory(hTargetProcess, 419 | (UCHAR*)ModuleImageBase + (USHORT)ulValue, 420 | pNtHeader32, 421 | sizeof(IMAGE_NT_HEADERS32), 422 | &ulBytesRead 423 | ); 424 | if (!bFlag) 425 | { 426 | break; 427 | } 428 | 429 | if ( (0 == pNtHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) \ 430 | || (0 == pNtHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) 431 | ) 432 | { 433 | break; 434 | } 435 | 436 | RemoteAddress = (UCHAR*)ModuleImageBase + pNtHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; 437 | } 438 | 439 | 440 | pExportDir = (IMAGE_EXPORT_DIRECTORY*)malloc( sizeof(IMAGE_EXPORT_DIRECTORY)); 441 | if (NULL == pExportDir) 442 | { 443 | break; 444 | } 445 | RtlZeroMemory(pExportDir , sizeof(IMAGE_EXPORT_DIRECTORY) ); 446 | 447 | bFlag = ReadProcessMemory(hTargetProcess, 448 | RemoteAddress, 449 | pExportDir, 450 | sizeof(IMAGE_EXPORT_DIRECTORY), 451 | &ulBytesRead 452 | ); 453 | if (!bFlag) 454 | { 455 | break; 456 | } 457 | 458 | FinalStatus = 0xC0000225L; 459 | for (i = 0; i < pExportDir->NumberOfNames; i++) 460 | { 461 | RemoteAddress = (UCHAR*)ModuleImageBase + pExportDir->AddressOfNames + i * sizeof(ULONG); 462 | 463 | RtlZeroMemory(pszFindName, MAX_PATH); 464 | 465 | //Read Name RVA 466 | ulValue = 0; 467 | bFlag = ReadProcessMemory(hTargetProcess, 468 | RemoteAddress, 469 | &ulValue, 470 | sizeof(ULONG), 471 | &ulBytesRead 472 | ); 473 | if (!bFlag) 474 | { 475 | continue; 476 | } 477 | 478 | bFlag = ReadProcessMemory(hTargetProcess, 479 | (UCHAR*)ModuleImageBase + (ULONG)ulValue, 480 | pszFindName, 481 | MAX_PATH, 482 | &ulBytesRead 483 | ); 484 | if (!bFlag) 485 | { 486 | continue; 487 | } 488 | 489 | 490 | if ( 0 == _stricmp(pszFindName , pszRoutineName) ) 491 | { 492 | //Read wNameOrdinal 493 | RemoteAddress = (USHORT*)( (UCHAR*)ModuleImageBase + pExportDir->AddressOfNameOrdinals ) + i; 494 | 495 | ulValue = 0; 496 | bFlag = ReadProcessMemory(hTargetProcess, 497 | RemoteAddress, 498 | &ulValue, 499 | sizeof(USHORT), 500 | &ulBytesRead 501 | ); 502 | if (bFlag) 503 | { 504 | if ( (USHORT)ulValue < pExportDir->NumberOfFunctions) 505 | { 506 | //Read Address RVA 507 | 508 | RemoteAddress = (ULONG*)( (UCHAR*)ModuleImageBase + pExportDir->AddressOfFunctions) + (USHORT)ulValue; 509 | 510 | ulValue = 0; 511 | bFlag = ReadProcessMemory(hTargetProcess, 512 | RemoteAddress, 513 | &ulValue, 514 | sizeof(ULONG), 515 | &ulBytesRead 516 | ); 517 | if (bFlag) 518 | { 519 | *ppRoutineAddress = (void*)( (UCHAR*)ModuleImageBase + (ULONG)ulValue); 520 | FinalStatus = 0; 521 | break; 522 | } 523 | } 524 | } 525 | } 526 | } 527 | 528 | } while (FALSE); 529 | 530 | if ( NULL != pszFindName) 531 | { 532 | free(pszFindName); 533 | pszFindName = NULL; 534 | } 535 | 536 | if ( NULL != pExportDir ) 537 | { 538 | free(pExportDir); 539 | pExportDir = NULL; 540 | } 541 | 542 | if ( NULL != pNtHeader32 ) 543 | { 544 | free(pNtHeader32); 545 | pNtHeader32 = NULL; 546 | } 547 | 548 | if ( NULL != pNtHeader64 ) 549 | { 550 | free( pNtHeader64 ); 551 | pNtHeader64 = NULL; 552 | } 553 | 554 | return FinalStatus; 555 | } 556 | 557 | 558 | LONG _RunWithDll_RemoteWriteString(__in HANDLE hProcess , __in BOOL bTarget64, __in WCHAR* pszString , __out void** ppRemoteUnicodeString) 559 | { 560 | #pragma pack(push,1) 561 | 562 | // 0x08 563 | typedef struct _UNICODE_STRING32 564 | { 565 | USHORT Length; //0x00 566 | USHORT MaximumLength; //0x00 567 | ULONG Buffer; //0x04 568 | } UNICODE_STRING32; 569 | 570 | #pragma pack(pop) 571 | 572 | // 0x10 573 | typedef struct _UNICODE_STRING64 574 | { 575 | USHORT Length; //0x00 576 | USHORT MaximumLength; //0x02 577 | ULONG64 Buffer; //0x08 578 | } UNICODE_STRING64; 579 | 580 | 581 | 582 | LONG FinalStatus = -1; 583 | 584 | int nSize = 0; 585 | 586 | int nWideSize = 0; 587 | 588 | UNICODE_STRING32 usHelp32 = {0}; 589 | UNICODE_STRING64 usHelp64 = {0}; 590 | 591 | void* pRemoteBuffer = NULL; 592 | void* pRemoteStr = NULL; 593 | ULONG_PTR BytesWritten = 0; 594 | 595 | int nRet = -1; 596 | BOOL bFlag = FALSE; 597 | 598 | 599 | do 600 | { 601 | if ( (NULL == pszString) || (NULL == ppRemoteUnicodeString) ) 602 | { 603 | break; 604 | } 605 | 606 | 607 | nWideSize = (int)( (wcslen(pszString) ) * sizeof(WCHAR) ); 608 | 609 | if (bTarget64) 610 | { 611 | nSize = nWideSize + sizeof(WCHAR) + 0x10; 612 | } 613 | else 614 | { 615 | nSize = nWideSize + sizeof(WCHAR) + 0x08; 616 | } 617 | 618 | pRemoteBuffer = VirtualAllocEx( 619 | hProcess , 620 | NULL, 621 | nSize, 622 | MEM_COMMIT |MEM_RESERVE , 623 | PAGE_READWRITE 624 | ); 625 | if (NULL == pRemoteBuffer) 626 | { 627 | break; 628 | } 629 | 630 | // write Struct 631 | if (bTarget64) 632 | { 633 | usHelp64.Length = (USHORT) nWideSize; 634 | usHelp64.MaximumLength = usHelp64.Length + sizeof(WCHAR); 635 | usHelp64.Buffer = (ULONG64)( (UCHAR*)pRemoteBuffer + 0x10 ); 636 | 637 | pRemoteStr = (void*)usHelp64.Buffer; 638 | } 639 | else 640 | { 641 | usHelp32.Length = (USHORT) nWideSize; 642 | usHelp32.MaximumLength = usHelp32.Length + sizeof(WCHAR); 643 | usHelp32.Buffer = (ULONG)( (UCHAR*)pRemoteBuffer + 0x08 ); 644 | 645 | pRemoteStr = (void*)usHelp32.Buffer; 646 | } 647 | 648 | 649 | if (bTarget64) 650 | { 651 | bFlag = WriteProcessMemory(hProcess, 652 | pRemoteBuffer, 653 | &usHelp64, 654 | sizeof(usHelp64), 655 | &BytesWritten 656 | ); 657 | } 658 | else 659 | { 660 | bFlag = WriteProcessMemory(hProcess, 661 | pRemoteBuffer, 662 | &usHelp32, 663 | sizeof(usHelp32), 664 | &BytesWritten 665 | ); 666 | } 667 | 668 | if (!bFlag) 669 | { 670 | break; 671 | } 672 | 673 | // write buffer 674 | bFlag = WriteProcessMemory(hProcess, 675 | pRemoteStr, 676 | pszString, 677 | nWideSize + sizeof(WCHAR), 678 | &BytesWritten 679 | ); 680 | if (!bFlag) 681 | { 682 | break; 683 | } 684 | 685 | *ppRemoteUnicodeString = pRemoteBuffer; 686 | 687 | FinalStatus = 0; 688 | } while (FALSE); 689 | 690 | return FinalStatus; 691 | } 692 | 693 | 694 | LONG _RunWithDll_RemotePrepareLoadEvent(__in HANDLE hProcess , __out HANDLE* phLocalLoadEvent , __out HANDLE* phRemoteLoadEvent) 695 | { 696 | LONG FinalStatus = -1; 697 | 698 | BOOL bFlag = FALSE; 699 | 700 | HANDLE hLocalLoadEvent = NULL; 701 | HANDLE hRemoteLoadEvent = NULL; 702 | 703 | 704 | do 705 | { 706 | hLocalLoadEvent = CreateEventW( NULL , TRUE , FALSE , NULL); 707 | if ( NULL == hLocalLoadEvent ) 708 | { 709 | break; 710 | } 711 | 712 | bFlag = DuplicateHandle( 713 | GetCurrentProcess(), 714 | hLocalLoadEvent , 715 | hProcess , 716 | &hRemoteLoadEvent, 717 | 0 , 718 | FALSE , 719 | DUPLICATE_SAME_ACCESS 720 | ); 721 | 722 | if ( !bFlag ) 723 | { 724 | CloseHandle(hLocalLoadEvent); 725 | hLocalLoadEvent = NULL; 726 | 727 | break; 728 | } 729 | 730 | FinalStatus = 0; 731 | } while (FALSE); 732 | 733 | if ( NULL != phLocalLoadEvent ) 734 | { 735 | *phLocalLoadEvent = hLocalLoadEvent; 736 | } 737 | 738 | if ( NULL != phRemoteLoadEvent) 739 | { 740 | *phRemoteLoadEvent = hRemoteLoadEvent; 741 | } 742 | 743 | return FinalStatus; 744 | } 745 | 746 | PVOID _RunWithDll_FindULONG32(__in PVOID pBase , __in ULONG nRange , __in ULONG nMagic ) 747 | { 748 | ULONG ulIndex=0; 749 | PVOID pFind=NULL; 750 | DWORD* pdwTemp=NULL; 751 | 752 | do 753 | { 754 | if ( (NULL == pBase) ) 755 | { 756 | break; 757 | } 758 | 759 | if ( nRange < sizeof(ULONG) ) 760 | { 761 | break; 762 | } 763 | 764 | for (ulIndex=0; ulIndex < (nRange - sizeof(ULONG)) ; ulIndex++) 765 | { 766 | pdwTemp = (ULONG*)((UCHAR*)pBase + ulIndex); 767 | if ( nMagic == (*pdwTemp) ) 768 | { 769 | pFind = (PVOID)pdwTemp; 770 | break; 771 | } 772 | } 773 | 774 | } while (FALSE); 775 | 776 | return pFind; 777 | } 778 | 779 | PVOID _RunWithDll_ReplaceULONG32(__in PVOID pAddr , __in ULONG nRange , __in ULONG nMagic , __in ULONG nValue , __in BOOLEAN bReplaceAll ) 780 | { 781 | UCHAR* pPos = NULL; 782 | UCHAR* pReturn = NULL; 783 | 784 | do 785 | { 786 | if ( (NULL == pAddr) || (0 == nRange) ) 787 | { 788 | break; 789 | } 790 | 791 | if (nRange < sizeof(ULONG)) 792 | { 793 | break; 794 | } 795 | 796 | 797 | for (pPos = (UCHAR*)pAddr; pPos <= (UCHAR*)pAddr + nRange - sizeof(ULONG); ) 798 | { 799 | 800 | if ( *(ULONG*)pPos == nMagic ) 801 | { 802 | *(ULONG*)pPos = nValue; 803 | 804 | if (bReplaceAll) 805 | { 806 | pPos += sizeof(ULONG); 807 | } 808 | else 809 | { 810 | pReturn = pPos + sizeof(ULONG); 811 | 812 | break; 813 | } 814 | } 815 | else 816 | { 817 | pPos++; 818 | } 819 | } 820 | 821 | } while (FALSE); 822 | 823 | return pReturn; 824 | } 825 | 826 | PVOID _RunWithDll_ReplaceULONG64(__in PVOID pAddr , __in ULONG nRange , __in ULONG64 nMagic , __in ULONG64 nValue , __in BOOLEAN bReplaceAll) 827 | { 828 | UCHAR* pPos = NULL; 829 | UCHAR* pReturn = NULL; 830 | 831 | do 832 | { 833 | if ( (NULL == pAddr) || (0 == nRange) ) 834 | { 835 | break; 836 | } 837 | 838 | if (nRange < sizeof(ULONG64)) 839 | { 840 | break; 841 | } 842 | 843 | for (pPos = (UCHAR*)pAddr; pPos <= (UCHAR*)pAddr + nRange - sizeof(ULONG64) ; ) 844 | { 845 | if ( *( (ULONG64*)pPos ) == nMagic) 846 | { 847 | *( (ULONG64*)pPos ) = nValue; 848 | 849 | if (bReplaceAll) 850 | { 851 | pPos += sizeof(ULONG64); 852 | } 853 | else 854 | { 855 | pReturn = pPos + sizeof(ULONG64); 856 | 857 | break; 858 | } 859 | } 860 | else 861 | { 862 | pPos++; 863 | } 864 | } 865 | 866 | } while (FALSE); 867 | 868 | return pReturn; 869 | } 870 | 871 | LONG _RunWithDll_BuildHookLdrLoadDllShellCode( 872 | __in HANDLE hTargetProcess , 873 | __in BOOL bTarget64 , 874 | __in void* pRemoteUnicodeString , 875 | __in void* pRemoteLdrLoadDll , 876 | __in void* pRemoteNtSetEvent , 877 | __in HANDLE hRemoteLoadEvent , 878 | __out void** ppCode , 879 | __out ULONG* pulCodeSize 880 | ) 881 | { 882 | LONG FinalStatus = -1; 883 | void* pOriginCode = NULL; 884 | 885 | void* pShellcode = NULL; 886 | ULONG ulCodeSize = 0; 887 | ULONG_PTR ulBytesRead = 0; 888 | BOOL bFlag = FALSE; 889 | 890 | unsigned char amd64_template[242] = { 891 | 0x90, 0x55, 0x48, 0x8B, 0xEC, 0x48, 0x83, 0xE4, 0xF0, 0x48, 0x81, 0xEC, 0x00, 0x02, 0x00, 0x00, 892 | 0x9C, 0x50, 0x51, 0x52, 0x53, 0x56, 0x57, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, 0x41, 893 | 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x56, 0x57, 0x51, 0xE9, 0xAB, 0x00, 0x00, 0x00, 0x48, 894 | 0xBF, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x48, 0xC7, 0xC1, 0x05, 0x00, 0x00, 0x00, 895 | 0xF3, 0xA4, 0x59, 0x5F, 0x5E, 0x51, 0x52, 0x48, 0x8D, 0x55, 0xE0, 0x48, 0xC7, 0x02, 0x00, 0x00, 896 | 0x00, 0x00, 0x48, 0xB9, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x48, 0xB8, 0x55, 0x55, 897 | 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x48, 0x81, 0xEC, 0x08, 0x01, 0x00, 0x00, 0xFF, 0xD0, 0x48, 898 | 0x81, 0xC4, 0x08, 0x01, 0x00, 0x00, 0x5A, 0x59, 0x4C, 0x8D, 0x4D, 0xE0, 0x49, 0xC7, 0x01, 0x00, 899 | 0x00, 0x00, 0x00, 0x49, 0xB8, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x48, 0x33, 0xD2, 900 | 0x48, 0xB8, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x48, 0x81, 0xEC, 0x08, 0x01, 0x00, 901 | 0x00, 0xFF, 0xD0, 0x48, 0x81, 0xC4, 0x08, 0x01, 0x00, 0x00, 0x41, 0x5F, 0x41, 0x5E, 0x41, 0x5D, 902 | 0x41, 0x5C, 0x41, 0x5B, 0x41, 0x5A, 0x41, 0x59, 0x41, 0x58, 0x5F, 0x5E, 0x5B, 0x5A, 0x59, 0x58, 903 | 0x9D, 0x48, 0x81, 0xC4, 0x00, 0x02, 0x00, 0x00, 0x48, 0x8B, 0xE5, 0x5D, 0xFF, 0x25, 0x00, 0x00, 904 | 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5E, 905 | 0x48, 0x83, 0xC6, 0x0A, 0xE9, 0x46, 0xFF, 0xFF, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 906 | 0x33, 0x90 907 | }; 908 | 909 | unsigned char i386_template[117] = { 910 | 0x90, 0x55, 0x8B, 0xEC, 0x83, 0xE4, 0xF0, 0x81, 0xEC, 0x00, 0x02, 0x00, 0x00, 0x9C, 0x60, 0x56, 911 | 0x57, 0x51, 0xEB, 0x51, 0xBF, 0x11, 0x11, 0x11, 0x11, 0xB9, 0x05, 0x00, 0x00, 0x00, 0xF3, 0xA4, 912 | 0x59, 0x5F, 0x5E, 0x8D, 0x45, 0xE0, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x68, 0x44, 0x44, 913 | 0x44, 0x44, 0xB8, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xD0, 0x8D, 0x45, 0xE0, 0xC7, 0x00, 0x00, 0x00, 914 | 0x00, 0x00, 0x50, 0x68, 0x22, 0x22, 0x22, 0x22, 0x6A, 0x00, 0xFF, 0x75, 0x08, 0xB8, 0x11, 0x11, 915 | 0x11, 0x11, 0xFF, 0xD0, 0x61, 0x9D, 0x81, 0xC4, 0x00, 0x02, 0x00, 0x00, 0x8B, 0xE5, 0x5D, 0x68, 916 | 0x11, 0x11, 0x11, 0x11, 0xC3, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x83, 0xC6, 0x06, 0xEB, 0xA4, 917 | 0x33, 0x33, 0x33, 0x33, 0x90 918 | }; 919 | 920 | do 921 | { 922 | if ( (0 == pRemoteUnicodeString) || (0 == pRemoteLdrLoadDll) || (NULL == ppCode) || (NULL == pulCodeSize) ) 923 | { 924 | break; 925 | } 926 | 927 | if (bTarget64) 928 | { 929 | ulCodeSize = sizeof(amd64_template); 930 | } 931 | else 932 | { 933 | ulCodeSize = sizeof(i386_template); 934 | } 935 | 936 | pShellcode = malloc( ulCodeSize); 937 | if (NULL == pShellcode) 938 | { 939 | break; 940 | } 941 | RtlZeroMemory(pShellcode , ulCodeSize); 942 | 943 | if (bTarget64) 944 | { 945 | RtlCopyMemory(pShellcode , amd64_template , sizeof(amd64_template)); 946 | } 947 | else 948 | { 949 | RtlCopyMemory(pShellcode , i386_template , sizeof(i386_template)); 950 | } 951 | 952 | if (bTarget64) 953 | { 954 | _RunWithDll_ReplaceULONG64( 955 | pShellcode, 956 | ulCodeSize, 957 | (ULONG64)0x1111111111111111, 958 | (ULONG64)pRemoteLdrLoadDll, 959 | TRUE 960 | ); 961 | 962 | _RunWithDll_ReplaceULONG64( 963 | pShellcode, 964 | ulCodeSize, 965 | (ULONG64)0x2222222222222222, 966 | (ULONG64)pRemoteUnicodeString, 967 | TRUE 968 | ); 969 | 970 | _RunWithDll_ReplaceULONG64( 971 | pShellcode, 972 | ulCodeSize, 973 | (ULONG64)0x4444444444444444, 974 | (ULONG64)hRemoteLoadEvent, 975 | TRUE 976 | ); 977 | 978 | _RunWithDll_ReplaceULONG64( 979 | pShellcode, 980 | ulCodeSize, 981 | (ULONG64)0x5555555555555555, 982 | (ULONG64)pRemoteNtSetEvent, 983 | TRUE 984 | ); 985 | } 986 | else 987 | { 988 | _RunWithDll_ReplaceULONG32( 989 | pShellcode, 990 | ulCodeSize, 991 | (ULONG64)0x11111111, 992 | (ULONG)((ULONG64)pRemoteLdrLoadDll), 993 | TRUE 994 | ); 995 | 996 | _RunWithDll_ReplaceULONG32( 997 | pShellcode, 998 | ulCodeSize, 999 | (ULONG64)0x22222222, 1000 | (ULONG)((ULONG64)pRemoteUnicodeString), 1001 | TRUE 1002 | ); 1003 | 1004 | _RunWithDll_ReplaceULONG32( 1005 | pShellcode, 1006 | ulCodeSize, 1007 | (ULONG64)0x44444444, 1008 | (ULONG)((ULONG64)hRemoteLoadEvent), 1009 | TRUE 1010 | ); 1011 | 1012 | _RunWithDll_ReplaceULONG32( 1013 | pShellcode, 1014 | ulCodeSize, 1015 | (ULONG64)0x55555555, 1016 | (ULONG)((ULONG64)pRemoteNtSetEvent), 1017 | TRUE 1018 | ); 1019 | } 1020 | 1021 | pOriginCode = _RunWithDll_FindULONG32( 1022 | pShellcode, 1023 | ulCodeSize, 1024 | (ULONG)0x33333333 1025 | ); 1026 | if (NULL == pOriginCode) 1027 | { 1028 | break; 1029 | } 1030 | 1031 | bFlag = ReadProcessMemory( 1032 | hTargetProcess, 1033 | pRemoteLdrLoadDll, 1034 | pOriginCode, 1035 | 5, 1036 | &ulBytesRead 1037 | ); 1038 | if (!bFlag) 1039 | { 1040 | break; 1041 | } 1042 | 1043 | *ppCode = pShellcode; 1044 | *pulCodeSize = ulCodeSize; 1045 | 1046 | FinalStatus = 0; 1047 | } while (FALSE); 1048 | 1049 | if (0 != FinalStatus) 1050 | { 1051 | if ( NULL != pShellcode) 1052 | { 1053 | free(pShellcode); 1054 | pShellcode = NULL; 1055 | } 1056 | } 1057 | 1058 | return FinalStatus; 1059 | } 1060 | 1061 | LONG _RunWithDll_RemoteAllocNearPageMemory( __in HANDLE hProcess , __in BOOL bTarget64, __in void* pNearBase , __in ULONG ulNeedSize , __in ULONG ulRangeSize , __out void** ppAllocatedMemAddress) 1062 | { 1063 | LONG Status = -1; 1064 | LONG FinalStatus = -1; 1065 | MEMORY_BASIC_INFORMATION stMemBasicInfo = {0}; 1066 | ULONG_PTR QueryAddress = (ULONG_PTR)pNearBase; 1067 | ULONG_PTR TryAddress = 0; 1068 | void* MemAddress = NULL; 1069 | void* FinalAddress = NULL; 1070 | ULONG ulPageSize = 0; 1071 | 1072 | do 1073 | { 1074 | if (bTarget64) 1075 | { 1076 | ulPageSize = 1024 * 8; 1077 | } 1078 | else 1079 | { 1080 | ulPageSize = 1024 * 4; 1081 | } 1082 | 1083 | for ( QueryAddress = (ULONG_PTR)pNearBase ; QueryAddress < (ULONG_PTR)pNearBase + ulRangeSize ; QueryAddress = QueryAddress + stMemBasicInfo.RegionSize) 1084 | { 1085 | RtlZeroMemory(&stMemBasicInfo, sizeof(stMemBasicInfo)); 1086 | 1087 | VirtualQueryEx(hProcess, (void*)QueryAddress, &stMemBasicInfo, sizeof(stMemBasicInfo)); 1088 | 1089 | if ( MEM_FREE != stMemBasicInfo.State) 1090 | { 1091 | continue; 1092 | } 1093 | 1094 | Status = -1; 1095 | for ( TryAddress = QueryAddress; TryAddress < QueryAddress + stMemBasicInfo.RegionSize; TryAddress = TryAddress + ulPageSize) 1096 | { 1097 | MemAddress = VirtualAllocEx(hProcess , (void*)TryAddress, ulNeedSize, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE); 1098 | if (NULL != MemAddress) 1099 | { 1100 | Status = 0; 1101 | break; 1102 | } 1103 | } 1104 | 1105 | if (0 == Status) 1106 | { 1107 | FinalAddress = MemAddress; 1108 | FinalStatus = 0; 1109 | break; 1110 | } 1111 | } 1112 | 1113 | } while (FALSE); 1114 | 1115 | if (NULL != ppAllocatedMemAddress) 1116 | { 1117 | *ppAllocatedMemAddress = FinalAddress; 1118 | } 1119 | 1120 | return FinalStatus; 1121 | } 1122 | 1123 | LONG _RunWithDll_RemoteWriteJump( __in HANDLE hTargetProcess , __in void* SourceAddress , __in void* DestAddress) 1124 | { 1125 | LONG FinalStatus = -1; 1126 | 1127 | UCHAR JumpCode[5] = {0}; 1128 | 1129 | ULONG64 Distance = 0; 1130 | 1131 | ULONG64 NextCode = 0; 1132 | LONG DisValue = 0; 1133 | ULONG_PTR BytesWritten = 0; 1134 | BOOL bFlag = FALSE; 1135 | 1136 | do 1137 | { 1138 | if ( (NULL == SourceAddress) || (NULL == DestAddress) ) 1139 | { 1140 | break; 1141 | } 1142 | 1143 | if ( (ULONG64)SourceAddress > (ULONG64)DestAddress ) 1144 | { 1145 | Distance = (ULONG64)SourceAddress - (ULONG64)DestAddress; 1146 | } 1147 | else 1148 | { 1149 | Distance = (ULONG64)DestAddress - (ULONG64)SourceAddress; 1150 | } 1151 | 1152 | if ( Distance > 0x7FFF0000) 1153 | { 1154 | break; 1155 | } 1156 | 1157 | NextCode = (ULONG64)SourceAddress + 5; 1158 | 1159 | DisValue = (LONG)((LONG64)DestAddress - (LONG64)NextCode); 1160 | 1161 | *( (UCHAR*)JumpCode + 0x00 ) = 0xE9; 1162 | 1163 | *( (ULONG*)( (UCHAR*)JumpCode + 1 ) ) = DisValue; 1164 | 1165 | bFlag = WriteProcessMemory(hTargetProcess, 1166 | SourceAddress, 1167 | JumpCode, 1168 | sizeof(JumpCode), 1169 | &BytesWritten 1170 | ); 1171 | if (!bFlag) 1172 | { 1173 | break; 1174 | } 1175 | 1176 | FinalStatus = 0; 1177 | } while (FALSE); 1178 | 1179 | return FinalStatus; 1180 | } 1181 | 1182 | LONG _RunWithDll_LdrInject(__in HANDLE hTargetProcess , __in HANDLE hTargetThread , __in WCHAR* pszTargetDll ) 1183 | { 1184 | LONG FinalStatus = -1; 1185 | LONG Status = 0; 1186 | WORD wArchitecture = 0; 1187 | BOOL bTarget64 = FALSE; 1188 | BOOL bFlag = FALSE; 1189 | 1190 | void* TargetNtdllImageBase = NULL; 1191 | void* TargetLdrLoadDll = NULL; 1192 | void* TargetNtSetEvent = NULL; 1193 | void* RemoteUnicodeStringDll = NULL; 1194 | 1195 | void* pLocalShellCode = NULL; 1196 | ULONG ulShellCodeSize = 0; 1197 | void* pRemoteShellcode = NULL; 1198 | ULONG_PTR ulBytesWriten = 0; 1199 | DWORD dwOldProtect = 0; 1200 | 1201 | HANDLE hLocalLoadEvent = NULL; 1202 | HANDLE hRemoteLoadEvent = NULL; 1203 | 1204 | do 1205 | { 1206 | if ( (NULL == hTargetProcess) || (NULL == pszTargetDll) ) 1207 | { 1208 | break; 1209 | } 1210 | 1211 | Status = _RunWithDll_GetTargetArchitecture(hTargetProcess , &wArchitecture); 1212 | if (0 != Status) 1213 | { 1214 | break; 1215 | } 1216 | 1217 | if ( PROCESSOR_ARCHITECTURE_AMD64 == wArchitecture) 1218 | { 1219 | bTarget64 = TRUE; 1220 | } 1221 | else 1222 | { 1223 | bTarget64 = FALSE; 1224 | } 1225 | 1226 | Status = _RunWithDll_RemotePrepareLoadEvent(hTargetProcess , &hLocalLoadEvent , &hRemoteLoadEvent); 1227 | if (0 != Status) 1228 | { 1229 | break; 1230 | } 1231 | 1232 | Status = _RunWithDll_RemoteWriteString(hTargetProcess, bTarget64, pszTargetDll, &RemoteUnicodeStringDll); 1233 | if (0 != Status) 1234 | { 1235 | break; 1236 | } 1237 | 1238 | Status = _RunWithDll_RemoteGetNtdllImageBase(hTargetProcess, bTarget64, &TargetNtdllImageBase); 1239 | if (0 != Status) 1240 | { 1241 | break; 1242 | } 1243 | 1244 | Status = _RunWithDll_RemoteGetProcAddress( 1245 | hTargetProcess, 1246 | bTarget64, 1247 | TargetNtdllImageBase, 1248 | "LdrLoadDll", 1249 | &TargetLdrLoadDll 1250 | ); 1251 | if (0 != Status) 1252 | { 1253 | break; 1254 | } 1255 | 1256 | Status = _RunWithDll_RemoteGetProcAddress( 1257 | hTargetProcess, 1258 | bTarget64, 1259 | TargetNtdllImageBase, 1260 | "NtSetEvent", 1261 | &TargetNtSetEvent 1262 | ); 1263 | if (0 != Status) 1264 | { 1265 | break; 1266 | } 1267 | 1268 | Status = _RunWithDll_BuildHookLdrLoadDllShellCode( 1269 | hTargetProcess, 1270 | bTarget64, 1271 | RemoteUnicodeStringDll, 1272 | TargetLdrLoadDll, 1273 | TargetNtSetEvent, 1274 | hRemoteLoadEvent, 1275 | &pLocalShellCode, 1276 | &ulShellCodeSize 1277 | ); 1278 | if (0 != Status) 1279 | { 1280 | break; 1281 | } 1282 | 1283 | Status = _RunWithDll_RemoteAllocNearPageMemory( 1284 | hTargetProcess, 1285 | bTarget64, 1286 | TargetNtdllImageBase, 1287 | ulShellCodeSize, 1288 | 0x7FFF0000, 1289 | &pRemoteShellcode 1290 | ); 1291 | if (0 != Status) 1292 | { 1293 | break; 1294 | } 1295 | 1296 | bFlag = WriteProcessMemory( 1297 | hTargetProcess, 1298 | pRemoteShellcode, 1299 | pLocalShellCode, 1300 | ulShellCodeSize, 1301 | &ulBytesWriten 1302 | ); 1303 | 1304 | if (!bFlag) 1305 | { 1306 | break; 1307 | } 1308 | 1309 | bFlag = VirtualProtectEx( 1310 | hTargetProcess, 1311 | (void*)TargetLdrLoadDll, 1312 | 5 , 1313 | PAGE_EXECUTE_READWRITE , 1314 | &dwOldProtect 1315 | ); 1316 | if (!bFlag) 1317 | { 1318 | break; 1319 | } 1320 | 1321 | Status = _RunWithDll_RemoteWriteJump(hTargetProcess , TargetLdrLoadDll, pRemoteShellcode); 1322 | if (0 != Status) 1323 | { 1324 | break; 1325 | } 1326 | 1327 | ResumeThread( hTargetThread); 1328 | 1329 | WaitForSingleObject(hLocalLoadEvent , INFINITE); 1330 | 1331 | bFlag = VirtualProtectEx( 1332 | hTargetProcess, 1333 | (void*)TargetLdrLoadDll, 1334 | 5 , 1335 | dwOldProtect , 1336 | &dwOldProtect 1337 | ); 1338 | if (!bFlag) 1339 | { 1340 | break; 1341 | } 1342 | 1343 | FinalStatus = 0; 1344 | } while (FALSE); 1345 | 1346 | if ( NULL != pLocalShellCode) 1347 | { 1348 | free( pLocalShellCode ); 1349 | pLocalShellCode = NULL; 1350 | } 1351 | 1352 | if ( NULL != hLocalLoadEvent) 1353 | { 1354 | CloseHandle(hLocalLoadEvent); 1355 | hLocalLoadEvent = NULL; 1356 | } 1357 | 1358 | return FinalStatus; 1359 | } 1360 | 1361 | 1362 | LONG RunWithDllW(__in WCHAR* pszApplication , __in_opt WCHAR* pszCommandline , __in WCHAR* pszTargetDll , __in ULONG nWaitTime) 1363 | { 1364 | LONG nFinalRet = -1; 1365 | LONG nRet = -1; 1366 | 1367 | STARTUPINFOW stStartupInfo = {0}; 1368 | PROCESS_INFORMATION stProcessInfo = {0}; 1369 | 1370 | ULONG nApplicationLen = 0; 1371 | ULONG nCommandlineLen = 0; 1372 | 1373 | ULONG nFixedLen = 0; 1374 | WCHAR* pszFixedCommandLine = NULL; 1375 | ULONG nDataLen = 0; 1376 | BOOL bNeedFree = FALSE; 1377 | 1378 | BOOL bFlag = FALSE; 1379 | 1380 | 1381 | do 1382 | { 1383 | stStartupInfo.cb = sizeof(stStartupInfo); 1384 | 1385 | if ( NULL == pszCommandline ) 1386 | { 1387 | pszFixedCommandLine = NULL; 1388 | } 1389 | else 1390 | { 1391 | nApplicationLen = (ULONG)wcslen( pszApplication ); 1392 | nCommandlineLen = (ULONG)wcslen( pszCommandline ); 1393 | 1394 | nFixedLen = nApplicationLen + 1 + nCommandlineLen + 1; 1395 | 1396 | pszFixedCommandLine = (WCHAR*)malloc( nFixedLen * sizeof(WCHAR) ); 1397 | if ( NULL == pszFixedCommandLine ) 1398 | { 1399 | break; 1400 | } 1401 | RtlZeroMemory( pszFixedCommandLine , nFixedLen * sizeof(WCHAR) ); 1402 | 1403 | bNeedFree = TRUE; 1404 | 1405 | nDataLen = 0; 1406 | 1407 | wcsncpy( pszFixedCommandLine + nDataLen, pszApplication , nApplicationLen ); 1408 | nDataLen += nApplicationLen; 1409 | 1410 | wcsncpy( pszFixedCommandLine + nDataLen , L" " , 1 ); 1411 | nDataLen += 1; 1412 | 1413 | wcsncpy( pszFixedCommandLine + nDataLen , pszCommandline , nCommandlineLen); 1414 | nDataLen += nCommandlineLen; 1415 | } 1416 | 1417 | bFlag = CreateProcessW( 1418 | pszApplication, 1419 | pszFixedCommandLine, 1420 | NULL, 1421 | NULL, 1422 | TRUE, 1423 | CREATE_SUSPENDED, 1424 | NULL, 1425 | NULL, 1426 | &stStartupInfo, 1427 | &stProcessInfo 1428 | ); 1429 | 1430 | if ( !bFlag) 1431 | { 1432 | break; 1433 | } 1434 | 1435 | nRet = _RunWithDll_LdrInject( stProcessInfo.hProcess , stProcessInfo.hThread , pszTargetDll ); 1436 | if ( 0 != nRet) 1437 | { 1438 | break; 1439 | } 1440 | 1441 | WaitForSingleObject( stProcessInfo.hProcess , nWaitTime ); 1442 | 1443 | nFinalRet = 0; 1444 | 1445 | } while (FALSE); 1446 | 1447 | if ( 0 != nFinalRet) 1448 | { 1449 | if (NULL != stProcessInfo.hProcess) 1450 | { 1451 | TerminateProcess( stProcessInfo.hProcess , 0 ); 1452 | } 1453 | 1454 | if (NULL != stProcessInfo.hThread) 1455 | { 1456 | TerminateThread( stProcessInfo.hThread , 0 ); 1457 | } 1458 | } 1459 | 1460 | if (NULL != stProcessInfo.hProcess) 1461 | { 1462 | CloseHandle(stProcessInfo.hProcess); 1463 | stProcessInfo.hProcess = NULL; 1464 | } 1465 | 1466 | if (NULL != stProcessInfo.hThread) 1467 | { 1468 | CloseHandle(stProcessInfo.hThread); 1469 | stProcessInfo.hThread = NULL; 1470 | } 1471 | 1472 | if ( bNeedFree ) 1473 | { 1474 | if ( NULL != pszFixedCommandLine ) 1475 | { 1476 | free( pszFixedCommandLine ); 1477 | pszFixedCommandLine = NULL; 1478 | } 1479 | } 1480 | 1481 | return nFinalRet; 1482 | } -------------------------------------------------------------------------------- /asm/amd64.asm: -------------------------------------------------------------------------------- 1 | ;Project: LdrInject amd64 2 | ;Author: root@tinysec.net 3 | ;File: main.asm of LdrInject amd64 4 | 5 | option casemap:none 6 | 7 | 8 | 9 | 10 | .code 11 | ;--------------------------------------------------------------------------- 12 | EntryPoint proc 13 | nop 14 | 15 | push rbp 16 | mov rbp , rsp 17 | and rsp , 0FFFFFFF0h 18 | sub rsp , 200h 19 | 20 | pushfq 21 | 22 | ; pushaq 23 | push rax 24 | push rcx 25 | push rdx 26 | push rbx 27 | push rsi 28 | push rdi 29 | push r8 30 | push r9 31 | push r10 32 | push r11 33 | push r12 34 | push r13 35 | push r14 36 | push r15 37 | 38 | push rsi 39 | push rdi 40 | push rcx 41 | 42 | jmp _restore_hook_prepare 43 | 44 | _restore_hook_start: 45 | mov rdi , 1111111111111111h ; LdrLoadDll 46 | mov rcx , 5 47 | rep movsb 48 | 49 | pop rcx 50 | pop rdi 51 | pop rsi 52 | 53 | _sign_event: 54 | 55 | lea rdx , [rbp - 20h] ; PreviousState 56 | mov QWORD PTR [rdx] , 0 57 | 58 | mov rcx , 4444444444444444h ; hLoadEvent 59 | mov rax , 5555555555555555h 60 | 61 | sub rsp , 108h 62 | call rax ; NtSetEvent 63 | add rsp , 108h 64 | 65 | _load_my_dll: 66 | 67 | lea r9 , [rbp - 20h] ; pModuleHandle 68 | mov QWORD PTR [r9] , 0 69 | 70 | mov r8 , 2222222222222222h ; pusDllFile 71 | xor rdx , rdx ; nFlags 72 | xor rcx , rcx ; pszSearchPath 73 | mov rax , 1111111111111111h ; LdrLoadDll 74 | 75 | sub rsp , 108h 76 | call rax 77 | add rsp , 108h 78 | 79 | _direct_ret: 80 | 81 | ; popaq 82 | pop r15 83 | pop r14 84 | pop r13 85 | pop r12 86 | pop r11 87 | pop r10 88 | pop r9 89 | pop r8 90 | pop rdi 91 | pop rsi 92 | pop rbx 93 | pop rdx 94 | pop rcx 95 | pop rax 96 | 97 | popfq 98 | 99 | add rsp , 200h 100 | mov rsp , rbp 101 | pop rbp 102 | 103 | ; jump to origin 104 | db 0FFh , 25h , 00h , 00h , 00h , 00h 105 | db 11h , 11h , 11h , 11h , 11h , 11h , 11h , 11h ; LdrLoadDll 106 | 107 | _restore_hook_prepare: 108 | call _get_savebytes_addr 109 | _get_savebytes_addr: 110 | pop rsi 111 | add rsi , 0Ah 112 | jmp _restore_hook_start 113 | 114 | ; saved bytes 115 | db 33h , 33h , 33h , 33h , 33h , 33h , 33h , 33h 116 | nop 117 | 118 | 119 | EntryPoint endp 120 | 121 | 122 | ;--------------------------------------------------------------------------- 123 | end 124 | -------------------------------------------------------------------------------- /asm/i386.asm: -------------------------------------------------------------------------------- 1 | ;Project: LdrInject i386 2 | ;Author: root@tinysec.net 3 | ;File: main.asm of LdrInject i386 4 | 5 | .686 6 | .xmm 7 | .mmx 8 | .model flat,stdcall 9 | option casemap:none 10 | 11 | .code 12 | ;--------------------------------------------------------------------------- 13 | EntryPoint proc 14 | nop 15 | 16 | push ebp 17 | mov ebp , esp 18 | and esp , 0FFFFFFF0h 19 | sub esp , 200h 20 | 21 | pushfd 22 | pushad 23 | 24 | push esi 25 | push edi 26 | push ecx 27 | 28 | jmp _restore_hook_prepare 29 | 30 | _restore_hook_start: 31 | mov edi , 11111111h ; LdrLoadDll 32 | mov ecx , 5 33 | rep movsb 34 | 35 | pop ecx 36 | pop edi 37 | pop esi 38 | 39 | 40 | _sign_event: 41 | 42 | lea eax , [ebp - 20h] 43 | mov DWORD PTR [eax] , 0 44 | push eax ; PreviousState 45 | 46 | push 44444444h ; hLoadEvent 47 | mov eax , 55555555h 48 | call eax ; NtSetEvent 49 | 50 | _load_my_dll: 51 | 52 | lea eax , [ebp - 20h] 53 | mov DWORD PTR [eax] , 0 54 | push eax ; pModuleHandle 55 | 56 | push 22222222h ; pusDllFile 57 | push 0 ; nFlags 58 | push 0 ; pszSearchPath 59 | mov eax , 11111111h ; LdrLoadDll 60 | call eax 61 | 62 | _direct_ret: 63 | popad 64 | popfd 65 | 66 | add esp , 200h 67 | mov esp , ebp 68 | pop ebp 69 | 70 | ; jump to origin 71 | push 11111111h ; LdrLoadDll 72 | ret 73 | 74 | _restore_hook_prepare: 75 | call _get_savebytes_addr 76 | _get_savebytes_addr: 77 | pop esi 78 | add esi , 6 79 | jmp _restore_hook_start 80 | 81 | ; saved bytes 82 | db 33h , 33h , 33h , 33h 83 | nop 84 | 85 | EntryPoint endp 86 | 87 | 88 | ;--------------------------------------------------------------------------- 89 | end EntryPoint 90 | --------------------------------------------------------------------------------