Snippet content copied to clipboard.
Are you sure to delete this snippet? No, don't delete
  1. ; #AutoIt3Wrapper_UseX64=n ; to run x86 from ScITE in x64 environment uncomment this
  2. ;.......script written by trancexx (trancexx at yahoo dot com)
  3. ; For this example just browse to some executable you wish to run from memory
  4. Global $sModule = FileOpenDialog("", "", "Executable modules (*.exe)")
  5. If @error Then Exit
  6. Global $bBinary = FileRead($sModule)
  7. Global $iNewPID
  8. ; Try 10 times in case of failures
  9. For $i = 1 To 10
  10. ConsoleWrite("Try No" & $i & @CRLF)
  11. $iNewPID = _RunBinary($bBinary);, "", @SystemDir & "\calc.exe") ; if it fails on for example XP, try another 'victim'.
  12. If Not @error Then ExitLoop
  13. Next
  14. ; Let's see if there were any errors
  15. Switch @error
  16. Case 0
  17. ConsoleWrite("New process sucessfully created. PID is: " & $iNewPID & @CRLF)
  18. Case 1
  19. MsgBox(48, "Error", "New process couldn't be created!" & @CRLF & "Check if the path is correct.")
  20. Case 2
  21. MsgBox(48, "Error", "Wrong AutoIt!" & @CRLF & "Should be x64 for x64 and x86 for x86.")
  22. Case 3
  23. MsgBox(48, "Error", "GetThreadContext function failed!" & @CRLF & "Something is wrong.")
  24. Case 4
  25. MsgBox(48, "Error", "Binary data seems to be corrupted!" & @CRLF & "MS-DOS header is wrong or missing.")
  26. Case 5
  27. MsgBox(48, "Error", "Binary data seems to be corrupted!" & @CRLF & "PE signature is wrong.")
  28. Case 6
  29. MsgBox(48, "Error", "Wrong AutoIt!" & @CRLF & "Should be x64 for x64 and x86 for x86.")
  30. Case 7
  31. MsgBox(48, "Error", "Internal error!" & @CRLF & "Failure while writting new module binary.")
  32. Case 8
  33. MsgBox(48, "Error", "Internal error!" & @CRLF & "Failure while filling PEB structure.")
  34. Case 9
  35. MsgBox(48, "Error", "Internal error!" & @CRLF & "Failure while changing base address.")
  36. Case 10
  37. MsgBox(48, "Error", "Internal error!" & @CRLF & "Failure with SetThreadContext function.")
  38. Case 11
  39. MsgBox(48, "Error", "Internal error!" & @CRLF & "Failure with ResumeThread function.")
  40. Case 101
  41. If @extended Then
  42. MsgBox(48, "Error", "Error!" & @CRLF & "Not enough space available at desired address. Try again maybe, or change the 'victim'.")
  43. Else
  44. MsgBox(48, "Error", "Error!" & @CRLF & "Executable you try to run is not relocatable. This lowers the possibility of running it in this fassion." & @CRLF & "Try again or find another 'victim', maybe you'll get lucky.")
  45. EndIf
  46. Case 102
  47. MsgBox(48, "Error", "Itanium architecture!" & @CRLF & "No solution. Sorry." & @CRLF & "How did you manage to end up here is beyond my comprehension.")
  48. EndSwitch
  49. ; FUNCTION
  50. Func _RunBinary($bBinaryImage, $sCommandLine = "", $sExeModule = @AutoItExe)
  51. #Region 1. DETERMINE INTERPRETER TYPE
  52. Local $fAutoItX64 = @AutoItX64
  53. #Region 2. PREDPROCESSING PASSED
  54. Local $bBinary = Binary($bBinaryImage) ; this is redundant but still...
  55. ; Make structure out of binary data that was passed
  56. Local $tBinary = DllStructCreate("byte[" & BinaryLen($bBinary) & "]")
  57. DllStructSetData($tBinary, 1, $bBinary) ; fill it
  58. ; Get pointer to it
  59. Local $pPointer = DllStructGetPtr($tBinary)
  60. #Region 3. CREATING NEW PROCESS
  61. ; STARTUPINFO structure (actually all that really matters is allocated space)
  62. Local $tSTARTUPINFO = DllStructCreate("dword cbSize;" & _
  63. "ptr Reserved;" & _
  64. "ptr Desktop;" & _
  65. "ptr Title;" & _
  66. "dword X;" & _
  67. "dword Y;" & _
  68. "dword XSize;" & _
  69. "dword YSize;" & _
  70. "dword XCountChars;" & _
  71. "dword YCountChars;" & _
  72. "dword FillAttribute;" & _
  73. "dword Flags;" & _
  74. "word ShowWindow;" & _
  75. "word Reserved2;" & _
  76. "ptr Reserved2;" & _
  77. "ptr hStdInput;" & _
  78. "ptr hStdOutput;" & _
  79. "ptr hStdError")
  80. ; This is much important. This structure will hold very some important data.
  81. Local $tPROCESS_INFORMATION = DllStructCreate("ptr Process;" & _
  82. "ptr Thread;" & _
  83. "dword ProcessId;" & _
  84. "dword ThreadId")
  85. ; Create new process
  86. Local $aCall = DllCall("kernel32.dll", "bool", "CreateProcessW", _
  87. "wstr", $sExeModule, _
  88. "wstr", $sCommandLine, _
  89. "ptr", 0, _
  90. "ptr", 0, _
  91. "int", 0, _
  92. "dword", 4, _ ; CREATE_SUSPENDED ; <- this is essential
  93. "ptr", 0, _
  94. "ptr", 0, _
  95. "ptr", DllStructGetPtr($tSTARTUPINFO), _
  96. "ptr", DllStructGetPtr($tPROCESS_INFORMATION))
  97. ; Check for errors or failure
  98. If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ; CreateProcess function or call to it failed
  99. ; Get new process and thread handles:
  100. Local $hProcess = DllStructGetData($tPROCESS_INFORMATION, "Process")
  101. Local $hThread = DllStructGetData($tPROCESS_INFORMATION, "Thread")
  102. ; Check for 'wrong' bit-ness. Not because it could't be implemented, but besause it would be uglyer (structures)
  103. If $fAutoItX64 And _RunBinary_IsWow64Process($hProcess) Then
  104. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  105. Return SetError(2, 0, 0)
  106. EndIf
  107. #Region 4. FILL CONTEXT STRUCTURE
  108. ; CONTEXT structure is what's really important here. It's processor specific.
  109. Local $iRunFlag, $tCONTEXT
  110. If $fAutoItX64 Then
  111. If @OSArch = "X64" Then
  112. $iRunFlag = 2
  113. $tCONTEXT = DllStructCreate("align 16; uint64 P1Home; uint64 P2Home; uint64 P3Home; uint64 P4Home; uint64 P5Home; uint64 P6Home;" & _ ; Register parameter home addresses
  114. "dword ContextFlags; dword MxCsr;" & _ ; Control flags
  115. "word SegCS; word SegDs; word SegEs; word SegFs; word SegGs; word SegSs; dword EFlags;" & _ ; Segment Registers and processor flags
  116. "uint64 Dr0; uint64 Dr1; uint64 Dr2; uint64 Dr3; uint64 Dr6; uint64 Dr7;" & _ ; Debug registers
  117. "uint64 Rax; uint64 Rcx; uint64 Rdx; uint64 Rbx; uint64 Rsp; uint64 Rbp; uint64 Rsi; uint64 Rdi; uint64 R8; uint64 R9; uint64 R10; uint64 R11; uint64 R12; uint64 R13; uint64 R14; uint64 R15;" & _ ; Integer registers
  118. "uint64 Rip;" & _ ; Program counter
  119. "uint64 Header[4]; uint64 Legacy[16]; uint64 Xmm0[2]; uint64 Xmm1[2]; uint64 Xmm2[2]; uint64 Xmm3[2]; uint64 Xmm4[2]; uint64 Xmm5[2]; uint64 Xmm6[2]; uint64 Xmm7[2]; uint64 Xmm8[2]; uint64 Xmm9[2]; uint64 Xmm10[2]; uint64 Xmm11[2]; uint64 Xmm12[2]; uint64 Xmm13[2]; uint64 Xmm14[2]; uint64 Xmm15[2];" & _ ; Floating point state (types are not correct for simplicity reasons!!!)
  120. "uint64 VectorRegister[52]; uint64 VectorControl;" & _ ; Vector registers (type for VectorRegister is not correct for simplicity reasons!!!)
  121. "uint64 DebugControl; uint64 LastBranchToRip; uint64 LastBranchFromRip; uint64 LastExceptionToRip; uint64 LastExceptionFromRip") ; Special debug control registers
  122. Else
  123. $iRunFlag = 3
  124. ; FIXME - Itanium architecture
  125. ; Return special error number:
  126. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  127. Return SetError(102, 0, 0)
  128. EndIf
  129. Else
  130. $iRunFlag = 1
  131. $tCONTEXT = DllStructCreate("dword ContextFlags;" & _ ; Control flags
  132. "dword Dr0; dword Dr1; dword Dr2; dword Dr3; dword Dr6; dword Dr7;" & _ ; CONTEXT_DEBUG_REGISTERS
  133. "dword ControlWord; dword StatusWord; dword TagWord; dword ErrorOffset; dword ErrorSelector; dword DataOffset; dword DataSelector; byte RegisterArea[80]; dword Cr0NpxState;" & _ ; CONTEXT_FLOATING_POINT
  134. "dword SegGs; dword SegFs; dword SegEs; dword SegDs;" & _ ; CONTEXT_SEGMENTS
  135. "dword Edi; dword Esi; dword Ebx; dword Edx; dword Ecx; dword Eax;" & _ ; CONTEXT_INTEGER
  136. "dword Ebp; dword Eip; dword SegCs; dword EFlags; dword Esp; dword SegSs;" & _ ; CONTEXT_CONTROL
  137. "byte ExtendedRegisters[512]") ; CONTEXT_EXTENDED_REGISTERS
  138. EndIf
  139. ; Define CONTEXT_FULL
  140. Local $CONTEXT_FULL
  141. Switch $iRunFlag
  142. Case 1
  143. $CONTEXT_FULL = 0x10007
  144. Case 2
  145. $CONTEXT_FULL = 0x100007
  146. Case 3
  147. $CONTEXT_FULL = 0x80027
  148. EndSwitch
  149. ; Set desired access
  150. DllStructSetData($tCONTEXT, "ContextFlags", $CONTEXT_FULL)
  151. ; Fill CONTEXT structure:
  152. $aCall = DllCall("kernel32.dll", "bool", "GetThreadContext", _
  153. "handle", $hThread, _
  154. "ptr", DllStructGetPtr($tCONTEXT))
  155. ; Check for errors or failure
  156. If @error Or Not $aCall[0] Then
  157. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  158. Return SetError(3, 0, 0) ; GetThreadContext function or call to it failed
  159. EndIf
  160. ; Pointer to PEB structure
  161. Local $pPEB
  162. Switch $iRunFlag
  163. Case 1
  164. $pPEB = DllStructGetData($tCONTEXT, "Ebx")
  165. Case 2
  166. $pPEB = DllStructGetData($tCONTEXT, "Rdx")
  167. Case 3
  168. ; NEVER BE - Itanium architecture
  169. EndSwitch
  170. #Region 5. READ PE-FORMAT
  171. ; Start processing passed binary data. 'Reading' PE format follows.
  172. ; First is IMAGE_DOS_HEADER
  173. Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _
  174. "word BytesOnLastPage;" & _
  175. "word Pages;" & _
  176. "word Relocations;" & _
  177. "word SizeofHeader;" & _
  178. "word MinimumExtra;" & _
  179. "word MaximumExtra;" & _
  180. "word SS;" & _
  181. "word SP;" & _
  182. "word Checksum;" & _
  183. "word IP;" & _
  184. "word CS;" & _
  185. "word Relocation;" & _
  186. "word Overlay;" & _
  187. "char Reserved[8];" & _
  188. "word OEMIdentifier;" & _
  189. "word OEMInformation;" & _
  190. "char Reserved2[20];" & _
  191. "dword AddressOfNewExeHeader", _
  192. $pPointer)
  193. ; Save this pointer value (it's starting address of binary image headers)
  194. Local $pHEADERS_NEW = $pPointer
  195. ; Move pointer
  196. $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header
  197. ; Get "Magic"
  198. Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic")
  199. ; Check if it's valid format
  200. If Not ($sMagic == "MZ") Then
  201. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  202. Return SetError(4, 0, 0) ; MS-DOS header missing.
  203. EndIf
  204. ; In place of IMAGE_NT_SIGNATURE
  205. Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer)
  206. ; Move pointer
  207. $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure
  208. ; Check signature
  209. If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE
  210. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  211. Return SetError(5, 0, 0) ; wrong signature. For PE image should be "PE\0\0" or 17744 dword.
  212. EndIf
  213. ; In place of IMAGE_FILE_HEADER
  214. Local $tIMAGE_FILE_HEADER = DllStructCreate("word Machine;" & _
  215. "word NumberOfSections;" & _
  216. "dword TimeDateStamp;" & _
  217. "dword PointerToSymbolTable;" & _
  218. "dword NumberOfSymbols;" & _
  219. "word SizeOfOptionalHeader;" & _
  220. "word Characteristics", _
  221. $pPointer)
  222. ; I could check here if the module is relocatable
  223. ; Local $fRelocatable
  224. ; If BitAND(DllStructGetData($tIMAGE_FILE_HEADER, "Characteristics"), 1) Then $fRelocatable = False
  225. ; But I won't (will check data in IMAGE_DIRECTORY_ENTRY_BASERELOC instead)
  226. ; Get number of sections
  227. Local $iNumberOfSections = DllStructGetData($tIMAGE_FILE_HEADER, "NumberOfSections")
  228. ; Move pointer
  229. $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure
  230. ; In place of IMAGE_OPTIONAL_HEADER
  231. Local $tMagic = DllStructCreate("word Magic;", $pPointer)
  232. Local $iMagic = DllStructGetData($tMagic, 1)
  233. Local $tIMAGE_OPTIONAL_HEADER
  234. If $iMagic = 267 Then ; x86 version
  235. If $fAutoItX64 Then
  236. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  237. Return SetError(6, 0, 0) ; incompatible versions
  238. EndIf
  239. $tIMAGE_OPTIONAL_HEADER = DllStructCreate("word Magic;" & _
  240. "byte MajorLinkerVersion;" & _
  241. "byte MinorLinkerVersion;" & _
  242. "dword SizeOfCode;" & _
  243. "dword SizeOfInitializedData;" & _
  244. "dword SizeOfUninitializedData;" & _
  245. "dword AddressOfEntryPoint;" & _
  246. "dword BaseOfCode;" & _
  247. "dword BaseOfData;" & _
  248. "dword ImageBase;" & _
  249. "dword SectionAlignment;" & _
  250. "dword FileAlignment;" & _
  251. "word MajorOperatingSystemVersion;" & _
  252. "word MinorOperatingSystemVersion;" & _
  253. "word MajorImageVersion;" & _
  254. "word MinorImageVersion;" & _
  255. "word MajorSubsystemVersion;" & _
  256. "word MinorSubsystemVersion;" & _
  257. "dword Win32VersionValue;" & _
  258. "dword SizeOfImage;" & _
  259. "dword SizeOfHeaders;" & _
  260. "dword CheckSum;" & _
  261. "word Subsystem;" & _
  262. "word DllCharacteristics;" & _
  263. "dword SizeOfStackReserve;" & _
  264. "dword SizeOfStackCommit;" & _
  265. "dword SizeOfHeapReserve;" & _
  266. "dword SizeOfHeapCommit;" & _
  267. "dword LoaderFlags;" & _
  268. "dword NumberOfRvaAndSizes", _
  269. $pPointer)
  270. ; Move pointer
  271. $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER
  272. ElseIf $iMagic = 523 Then ; x64 version
  273. If Not $fAutoItX64 Then
  274. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  275. Return SetError(6, 0, 0) ; incompatible versions
  276. EndIf
  277. $tIMAGE_OPTIONAL_HEADER = DllStructCreate("word Magic;" & _
  278. "byte MajorLinkerVersion;" & _
  279. "byte MinorLinkerVersion;" & _
  280. "dword SizeOfCode;" & _
  281. "dword SizeOfInitializedData;" & _
  282. "dword SizeOfUninitializedData;" & _
  283. "dword AddressOfEntryPoint;" & _
  284. "dword BaseOfCode;" & _
  285. "uint64 ImageBase;" & _
  286. "dword SectionAlignment;" & _
  287. "dword FileAlignment;" & _
  288. "word MajorOperatingSystemVersion;" & _
  289. "word MinorOperatingSystemVersion;" & _
  290. "word MajorImageVersion;" & _
  291. "word MinorImageVersion;" & _
  292. "word MajorSubsystemVersion;" & _
  293. "word MinorSubsystemVersion;" & _
  294. "dword Win32VersionValue;" & _
  295. "dword SizeOfImage;" & _
  296. "dword SizeOfHeaders;" & _
  297. "dword CheckSum;" & _
  298. "word Subsystem;" & _
  299. "word DllCharacteristics;" & _
  300. "uint64 SizeOfStackReserve;" & _
  301. "uint64 SizeOfStackCommit;" & _
  302. "uint64 SizeOfHeapReserve;" & _
  303. "uint64 SizeOfHeapCommit;" & _
  304. "dword LoaderFlags;" & _
  305. "dword NumberOfRvaAndSizes", _
  306. $pPointer)
  307. ; Move pointer
  308. $pPointer += 112 ; size of $tIMAGE_OPTIONAL_HEADER
  309. Else
  310. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  311. Return SetError(6, 0, 0) ; incompatible versions
  312. EndIf
  313. ; Extract entry point address
  314. Local $iEntryPointNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "AddressOfEntryPoint") ; if loaded binary image would start executing at this address
  315. ; And other interesting informations
  316. Local $iOptionalHeaderSizeOfHeadersNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "SizeOfHeaders")
  317. Local $pOptionalHeaderImageBaseNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "ImageBase") ; address of the first byte of the image when it's loaded in memory
  318. Local $iOptionalHeaderSizeOfImageNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "SizeOfImage") ; the size of the image including all headers
  319. ; Move pointer
  320. $pPointer += 8 ; skipping IMAGE_DIRECTORY_ENTRY_EXPORT
  321. $pPointer += 8 ; size of $tIMAGE_DIRECTORY_ENTRY_IMPORT
  322. $pPointer += 24 ; skipping IMAGE_DIRECTORY_ENTRY_RESOURCE, IMAGE_DIRECTORY_ENTRY_EXCEPTION, IMAGE_DIRECTORY_ENTRY_SECURITY
  323. ; Base Relocation Directory
  324. Local $tIMAGE_DIRECTORY_ENTRY_BASERELOC = DllStructCreate("dword VirtualAddress; dword Size", $pPointer)
  325. ; Collect data
  326. Local $pAddressNewBaseReloc = DllStructGetData($tIMAGE_DIRECTORY_ENTRY_BASERELOC, "VirtualAddress")
  327. Local $iSizeBaseReloc = DllStructGetData($tIMAGE_DIRECTORY_ENTRY_BASERELOC, "Size")
  328. Local $fRelocatable
  329. If $pAddressNewBaseReloc And $iSizeBaseReloc Then $fRelocatable = True
  330. If Not $fRelocatable Then ConsoleWrite("!!!NOT RELOCATABLE MODULE. I WILL TRY BUT THIS MAY NOT WORK!!!" & @CRLF) ; nothing can be done here
  331. ; Move pointer
  332. $pPointer += 88 ; size of the structures before IMAGE_SECTION_HEADER (16 of them).
  333. #Region 6. ALLOCATE 'NEW' MEMORY SPACE
  334. Local $fRelocate
  335. Local $pZeroPoint
  336. If $fRelocatable Then ; If the module can be relocated then allocate memory anywhere possible
  337. $pZeroPoint = _RunBinary_AllocateExeSpace($hProcess, $iOptionalHeaderSizeOfImageNEW)
  338. ; In case of failure try at original address
  339. If @error Then
  340. $pZeroPoint = _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pOptionalHeaderImageBaseNEW, $iOptionalHeaderSizeOfImageNEW)
  341. If @error Then
  342. _RunBinary_UnmapViewOfSection($hProcess, $pOptionalHeaderImageBaseNEW)
  343. ; Try now
  344. $pZeroPoint = _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pOptionalHeaderImageBaseNEW, $iOptionalHeaderSizeOfImageNEW)
  345. If @error Then
  346. ; Return special error number:
  347. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  348. Return SetError(101, 1, 0)
  349. EndIf
  350. EndIf
  351. EndIf
  352. $fRelocate = True
  353. Else ; And if not try where it should be
  354. $pZeroPoint = _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pOptionalHeaderImageBaseNEW, $iOptionalHeaderSizeOfImageNEW)
  355. If @error Then
  356. _RunBinary_UnmapViewOfSection($hProcess, $pOptionalHeaderImageBaseNEW)
  357. ; Try now
  358. $pZeroPoint = _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pOptionalHeaderImageBaseNEW, $iOptionalHeaderSizeOfImageNEW)
  359. If @error Then
  360. ; Return special error number:
  361. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  362. Return SetError(101, 0, 0)
  363. EndIf
  364. EndIf
  365. EndIf
  366. ; If there is new ImageBase value, save it
  367. DllStructSetData($tIMAGE_OPTIONAL_HEADER, "ImageBase", $pZeroPoint)
  368. #Region 7. CONSTRUCT THE NEW MODULE
  369. ; Allocate enough space (in our space) for the new module
  370. Local $tModule = DllStructCreate("byte[" & $iOptionalHeaderSizeOfImageNEW & "]")
  371. ; Get pointer
  372. Local $pModule = DllStructGetPtr($tModule)
  373. ; Headers
  374. Local $tHeaders = DllStructCreate("byte[" & $iOptionalHeaderSizeOfHeadersNEW & "]", $pHEADERS_NEW)
  375. ; Write headers to $tModule
  376. DllStructSetData($tModule, 1, DllStructGetData($tHeaders, 1))
  377. ; Write sections now. $pPointer is currently in place of sections
  378. Local $tIMAGE_SECTION_HEADER
  379. Local $iSizeOfRawData, $pPointerToRawData
  380. Local $iVirtualAddress, $iVirtualSize
  381. Local $tRelocRaw
  382. ; Loop through sections
  383. For $i = 1 To $iNumberOfSections
  384. $tIMAGE_SECTION_HEADER = DllStructCreate("char Name[8];" & _
  385. "dword UnionOfVirtualSizeAndPhysicalAddress;" & _
  386. "dword VirtualAddress;" & _
  387. "dword SizeOfRawData;" & _
  388. "dword PointerToRawData;" & _
  389. "dword PointerToRelocations;" & _
  390. "dword PointerToLinenumbers;" & _
  391. "word NumberOfRelocations;" & _
  392. "word NumberOfLinenumbers;" & _
  393. "dword Characteristics", _
  394. $pPointer)
  395. ; Collect data
  396. $iSizeOfRawData = DllStructGetData($tIMAGE_SECTION_HEADER, "SizeOfRawData")
  397. $pPointerToRawData = $pHEADERS_NEW + DllStructGetData($tIMAGE_SECTION_HEADER, "PointerToRawData")
  398. $iVirtualAddress = DllStructGetData($tIMAGE_SECTION_HEADER, "VirtualAddress")
  399. $iVirtualSize = DllStructGetData($tIMAGE_SECTION_HEADER, "UnionOfVirtualSizeAndPhysicalAddress")
  400. If $iVirtualSize And $iVirtualSize < $iSizeOfRawData Then $iSizeOfRawData = $iVirtualSize
  401. ; If there is data to write, write it
  402. If $iSizeOfRawData Then
  403. DllStructSetData(DllStructCreate("byte[" & $iSizeOfRawData & "]", $pModule + $iVirtualAddress), 1, DllStructGetData(DllStructCreate("byte[" & $iSizeOfRawData & "]", $pPointerToRawData), 1))
  404. EndIf
  405. ; Relocations
  406. If $fRelocate Then
  407. If $iVirtualAddress <= $pAddressNewBaseReloc And $iVirtualAddress + $iSizeOfRawData > $pAddressNewBaseReloc Then
  408. $tRelocRaw = DllStructCreate("byte[" & $iSizeBaseReloc & "]", $pPointerToRawData + ($pAddressNewBaseReloc - $iVirtualAddress))
  409. EndIf
  410. EndIf
  411. ; Move pointer
  412. $pPointer += 40 ; size of $tIMAGE_SECTION_HEADER structure
  413. Next
  414. ; Fix relocations
  415. If $fRelocate Then _RunBinary_FixReloc($pModule, $tRelocRaw, $pZeroPoint, $pOptionalHeaderImageBaseNEW, $iMagic = 523)
  416. ; Write newly constructed module to allocated space inside the $hProcess
  417. $aCall = DllCall("kernel32.dll", "bool", _RunBinary_LeanAndMean(), _
  418. "handle", $hProcess, _
  419. "ptr", $pZeroPoint, _
  420. "ptr", $pModule, _
  421. "dword_ptr", $iOptionalHeaderSizeOfImageNEW, _
  422. "dword_ptr*", 0)
  423. ; Check for errors or failure
  424. If @error Or Not $aCall[0] Then
  425. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  426. Return SetError(7, 0, 0) ; failure while writting new module binary
  427. EndIf
  428. #Region 8. PEB ImageBaseAddress MANIPULATION
  429. ; PEB structure definition
  430. Local $tPEB = DllStructCreate("byte InheritedAddressSpace;" & _
  431. "byte ReadImageFileExecOptions;" & _
  432. "byte BeingDebugged;" & _
  433. "byte Spare;" & _
  434. "ptr Mutant;" & _
  435. "ptr ImageBaseAddress;" & _
  436. "ptr LoaderData;" & _
  437. "ptr ProcessParameters;" & _
  438. "ptr SubSystemData;" & _
  439. "ptr ProcessHeap;" & _
  440. "ptr FastPebLock;" & _
  441. "ptr FastPebLockRoutine;" & _
  442. "ptr FastPebUnlockRoutine;" & _
  443. "dword EnvironmentUpdateCount;" & _
  444. "ptr KernelCallbackTable;" & _
  445. "ptr EventLogSection;" & _
  446. "ptr EventLog;" & _
  447. "ptr FreeList;" & _
  448. "dword TlsExpansionCounter;" & _
  449. "ptr TlsBitmap;" & _
  450. "dword TlsBitmapBits[2];" & _
  451. "ptr ReadOnlySharedMemoryBase;" & _
  452. "ptr ReadOnlySharedMemoryHeap;" & _
  453. "ptr ReadOnlyStaticServerData;" & _
  454. "ptr AnsiCodePageData;" & _
  455. "ptr OemCodePageData;" & _
  456. "ptr UnicodeCaseTableData;" & _
  457. "dword NumberOfProcessors;" & _
  458. "dword NtGlobalFlag;" & _
  459. "byte Spare2[4];" & _
  460. "int64 CriticalSectionTimeout;" & _
  461. "dword HeapSegmentReserve;" & _
  462. "dword HeapSegmentCommit;" & _
  463. "dword HeapDeCommitTotalFreeThreshold;" & _
  464. "dword HeapDeCommitFreeBlockThreshold;" & _
  465. "dword NumberOfHeaps;" & _
  466. "dword MaximumNumberOfHeaps;" & _
  467. "ptr ProcessHeaps;" & _
  468. "ptr GdiSharedHandleTable;" & _
  469. "ptr ProcessStarterHelper;" & _
  470. "ptr GdiDCAttributeList;" & _
  471. "ptr LoaderLock;" & _
  472. "dword OSMajorVersion;" & _
  473. "dword OSMinorVersion;" & _
  474. "dword OSBuildNumber;" & _
  475. "dword OSPlatformId;" & _
  476. "dword ImageSubSystem;" & _
  477. "dword ImageSubSystemMajorVersion;" & _
  478. "dword ImageSubSystemMinorVersion;" & _
  479. "dword GdiHandleBuffer[34];" & _
  480. "dword PostProcessInitRoutine;" & _
  481. "dword TlsExpansionBitmap;" & _
  482. "byte TlsExpansionBitmapBits[128];" & _
  483. "dword SessionId")
  484. ; Fill the structure
  485. $aCall = DllCall("kernel32.dll", "bool", "ReadProcessMemory", _
  486. "ptr", $hProcess, _
  487. "ptr", $pPEB, _ ; pointer to PEB structure
  488. "ptr", DllStructGetPtr($tPEB), _
  489. "dword_ptr", DllStructGetSize($tPEB), _
  490. "dword_ptr*", 0)
  491. ; Check for errors or failure
  492. If @error Or Not $aCall[0] Then
  493. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  494. Return SetError(8, 0, 0) ; ReadProcessMemory function or call to it failed while filling PEB structure
  495. EndIf
  496. ; Change base address within PEB
  497. DllStructSetData($tPEB, "ImageBaseAddress", $pZeroPoint)
  498. ; Write the changes
  499. $aCall = DllCall("kernel32.dll", "bool", _RunBinary_LeanAndMean(), _
  500. "handle", $hProcess, _
  501. "ptr", $pPEB, _
  502. "ptr", DllStructGetPtr($tPEB), _
  503. "dword_ptr", DllStructGetSize($tPEB), _
  504. "dword_ptr*", 0)
  505. ; Check for errors or failure
  506. If @error Or Not $aCall[0] Then
  507. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  508. Return SetError(9, 0, 0) ; failure while changing base address
  509. EndIf
  510. #Region 9. NEW ENTRY POINT
  511. ; Entry point manipulation
  512. Switch $iRunFlag
  513. Case 1
  514. DllStructSetData($tCONTEXT, "Eax", $pZeroPoint + $iEntryPointNEW)
  515. Case 2
  516. DllStructSetData($tCONTEXT, "Rcx", $pZeroPoint + $iEntryPointNEW)
  517. Case 3
  518. ; FIXME - Itanium architecture
  519. EndSwitch
  520. #Region 10. SET NEW CONTEXT
  521. ; New context:
  522. $aCall = DllCall("kernel32.dll", "bool", "SetThreadContext", _
  523. "handle", $hThread, _
  524. "ptr", DllStructGetPtr($tCONTEXT))
  525. If @error Or Not $aCall[0] Then
  526. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  527. Return SetError(10, 0, 0) ; SetThreadContext function or call to it failed
  528. EndIf
  529. #Region 11. RESUME THREAD
  530. ; And that's it!. Continue execution:
  531. $aCall = DllCall("kernel32.dll", "dword", "ResumeThread", "handle", $hThread)
  532. ; Check for errors or failure
  533. If @error Or $aCall[0] = -1 Then
  534. DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  535. Return SetError(11, 0, 0) ; ResumeThread function or call to it failed
  536. EndIf
  537. #Region 12. CLOSE OPEN HANDLES AND RETURN PID
  538. DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hProcess)
  539. DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hThread)
  540. ; All went well. Return new PID:
  541. Return DllStructGetData($tPROCESS_INFORMATION, "ProcessId")
  542. EndFunc
  543. Func _RunBinary_LeanAndMean()
  544. Local $aArr[18] = ["W", "r", "i", "t", "e", "P", "r", "o", "c", "e", "s", "s", "M", "e", "m", "o", "r", "y"], $sOut
  545. For $sChar In $aArr
  546. $sOut &= $sChar
  547. Next
  548. Return $sOut
  549. EndFunc
  550. Func _RunBinary_FixReloc($pModule, $tData, $pAddressNew, $pAddressOld, $fImageX64)
  551. Local $iDelta = $pAddressNew - $pAddressOld ; dislocation value
  552. Local $iSize = DllStructGetSize($tData) ; size of data
  553. Local $pData = DllStructGetPtr($tData) ; addres of the data structure
  554. Local $tIMAGE_BASE_RELOCATION, $iRelativeMove
  555. Local $iVirtualAddress, $iSizeofBlock, $iNumberOfEntries
  556. Local $tEnries, $iData, $tAddress
  557. Local $iFlag = 3 + 7 * $fImageX64 ; IMAGE_REL_BASED_HIGHLOW = 3 or IMAGE_REL_BASED_DIR64 = 10
  558. While $iRelativeMove < $iSize ; for all data available
  559. $tIMAGE_BASE_RELOCATION = DllStructCreate("dword VirtualAddress; dword SizeOfBlock", $pData + $iRelativeMove)
  560. $iVirtualAddress = DllStructGetData($tIMAGE_BASE_RELOCATION, "VirtualAddress")
  561. $iSizeofBlock = DllStructGetData($tIMAGE_BASE_RELOCATION, "SizeOfBlock")
  562. $iNumberOfEntries = ($iSizeofBlock - 8) / 2
  563. $tEnries = DllStructCreate("word[" & $iNumberOfEntries & "]", DllStructGetPtr($tIMAGE_BASE_RELOCATION) + 8)
  564. ; Go through all entries
  565. For $i = 1 To $iNumberOfEntries
  566. $iData = DllStructGetData($tEnries, 1, $i)
  567. If BitShift($iData, 12) = $iFlag Then ; check type
  568. $tAddress = DllStructCreate("ptr", $pModule + $iVirtualAddress + BitAND($iData, 0xFFF)) ; the rest of $iData is offset
  569. DllStructSetData($tAddress, 1, DllStructGetData($tAddress, 1) + $iDelta) ; this is what's this all about
  570. EndIf
  571. Next
  572. $iRelativeMove += $iSizeofBlock
  573. WEnd
  574. Return 1 ; all OK!
  575. EndFunc
  576. Func _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pAddress, $iSize)
  577. ; Allocate
  578. Local $aCall = DllCall("kernel32.dll", "ptr", "VirtualAllocEx", _
  579. "handle", $hProcess, _
  580. "ptr", $pAddress, _
  581. "dword_ptr", $iSize, _
  582. "dword", 0x1000, _ ; MEM_COMMIT
  583. "dword", 64) ; PAGE_EXECUTE_READWRITE
  584. ; Check for errors or failure
  585. If @error Or Not $aCall[0] Then
  586. ; Try differently
  587. $aCall = DllCall("kernel32.dll", "ptr", "VirtualAllocEx", _
  588. "handle", $hProcess, _
  589. "ptr", $pAddress, _
  590. "dword_ptr", $iSize, _
  591. "dword", 0x3000, _ ; MEM_COMMIT|MEM_RESERVE
  592. "dword", 64) ; PAGE_EXECUTE_READWRITE
  593. ; Check for errors or failure
  594. If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ; Unable to allocate
  595. EndIf
  596. Return $aCall[0]
  597. EndFunc
  598. Func _RunBinary_AllocateExeSpace($hProcess, $iSize)
  599. ; Allocate space
  600. Local $aCall = DllCall("kernel32.dll", "ptr", "VirtualAllocEx", _
  601. "handle", $hProcess, _
  602. "ptr", 0, _
  603. "dword_ptr", $iSize, _
  604. "dword", 0x3000, _ ; MEM_COMMIT|MEM_RESERVE
  605. "dword", 64) ; PAGE_EXECUTE_READWRITE
  606. ; Check for errors or failure
  607. If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ; Unable to allocate
  608. Return $aCall[0]
  609. EndFunc
  610. Func _RunBinary_UnmapViewOfSection($hProcess, $pAddress)
  611. DllCall("ntdll.dll", "int", "NtUnmapViewOfSection", _
  612. "ptr", $hProcess, _
  613. "ptr", $pAddress)
  614. ; Check for errors only
  615. If @error Then Return SetError(1, 0, 0) ; Failure
  616. Return 1
  617. EndFunc
  618. Func _RunBinary_IsWow64Process($hProcess)
  619. Local $aCall = DllCall("kernel32.dll", "bool", "IsWow64Process", _
  620. "handle", $hProcess, _
  621. "bool*", 0)
  622. ; Check for errors or failure
  623. If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ; Failure
  624. Return $aCall[2]
  625. EndFunc

Edit this Snippet