[C#] ASM Injection (CreateRemoteThread) menu

User Tag List

Results 1 to 8 of 8
  1. #1
    Xartrick's Avatar Active Member
    Reputation
    24
    Join Date
    May 2011
    Posts
    29
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [C#] ASM Injection (CreateRemoteThread)

    Hello.

    In this entry, we will see how to inject and execute ASM (shellcode) using CreateRemoteThread in x86 environment (I don't even test it on x64 since my computers all running on x86).

    This API create (and execute if correct flag is provided) a thread where we put our shellcode using WriteProcessMemory.

    So, the basic scheme is:

    * Get process handle using OpenProcess
    * Allocate memory for our shellcode using VirtualAllocEx
    * Write our shellcode using WriteProcessMemory
    * Create and execute a thread on our shellcode using CreateRemoteThread
    * Close process and thread handle using CloseHandle

    All these imports are from pinvoke.net, so thanks for this useful wiki.

    Code:
    [DllImport("kernel32.dll")]
    public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
    [DllImport("kernel32.dll")]
    public static extern bool CloseHandle(IntPtr hObject);
    
    [DllImport("kernel32.dll")]
    public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
    
    [DllImport("kernel32.dll")]
    public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
    
    [DllImport("kernel32.dll")]
    public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId);
    Code:
    [Flags]
    public enum ProcessAccessFlags : uint {
    	Terminate        = 0x00000001,
    	CreateThread     = 0x00000002,
    	VMOperation      = 0x00000008,
    	VMRead           = 0x00000010,
    	VMWrite          = 0x00000020,
    	DupHandle        = 0x00000040,
    	SetInformation   = 0x00000200,
    	QueryInformation = 0x00000400,
    	Synchronize      = 0x00100000,
    	All              = 0x001F0FFF
    }
    
    [Flags]
    public enum AllocationType {
    	 Commit     = 0x00001000,
    	 Reserve    = 0x00002000,
    	 Decommit   = 0x00004000,
    	 Release    = 0x00008000,
    	 Reset      = 0x00080000,
    	 TopDown    = 0x00100000,
    	 WriteWatch = 0x00200000,
    	 Physical   = 0x00400000,
    	 LargePages = 0x20000000
    }
    
    [Flags]
    public enum MemoryProtection {
    	 NoAccess                 = 0x0001,
    	 ReadOnly                 = 0x0002,
    	 ReadWrite                = 0x0004,
    	 WriteCopy                = 0x0008,
    	 Execute                  = 0x0010,
    	 ExecuteRead              = 0x0020,
    	 ExecuteReadWrite         = 0x0040,
    	 ExecuteWriteCopy         = 0x0080,
    	 GuardModifierflag        = 0x0100,
    	 NoCacheModifierflag      = 0x0200,
    	 WriteCombineModifierflag = 0x0400
    }
    Here is the shellcode we will use, it's a simple WinExec who exec calc.exe, I get it here.
    You will have to edit the shellcode to align the stack to have a correct RET instruction and exit the thread.
    If not, the application will crash.

    Code:
    byte[] asm = new byte[] {
    	0x31, 0xD2,                               // XOR   EDX, EDX
    	0x52,                                     // PUSH  EDX
    	0x68, 0x63, 0x61, 0x6C, 0x63,             // PUSH  'calc'
    	0x89, 0xE6,                               // MOV   ESI, ESP
    	0x52,                                     // PUSH  EDX
    	0x56,                                     // PUSH  ESI
    	0x64, 0x8B, 0x72, 0x30,                   // MOV   ESI, DWORD PTR FS:[EDX+30]
    	0x8B, 0x76, 0x0C,                         // MOV   ESI, DWORD PTR DS:[ESI+C]
    	0x8B, 0x76, 0x0C,                         // MOV   ESI, DWORD PTR DS:[ESI+C]
    	0xAD,                                     // LODS  DWORD PTR DS:[ESI]
    	0x8B, 0x30,                               // MOV   ESI, DWORD PTR DS:[EAX]
    	0x8B, 0x7E, 0x18,                         // MOV   EDI, DWORD PTR DS:[ESI+18]
    	0x8B, 0x5F, 0x3C,                         // MOV   EBX, DWORD PTR DS:[EDI+3C]
    	0x8B, 0x5C, 0x1F, 0x78,                   // MOV   EBX, DWORD PTR DS:[EDI+EBX+78]
    	0x8B, 0x74, 0x1F, 0x20,                   // MOV   ESI, DWORD PTR DS:[EDI+EBX+20]
    	0x01, 0xFE,                               // ADD   ESI, EDI
    	0x8B, 0x4C, 0x1F, 0x24,                   // MOV   ECX, DWORD PTR DS:[EDI+EBX+24]
    	0x01, 0xF9,                               // ADD   ECX, EDI
    	//                                           label1:
    	0x0F, 0xB7, 0x2C, 0x51,                   // MOVZX EBP, WORD PTR DS:[ECX+EDX*2]
    	0x42,                                     // INC   EDX
    	0xAD,                                     // LODS  DWORD PTR DS:[ESI]
    	0x81, 0x3C, 0x07, 0x57, 0x69, 0x6E, 0x45, // CMP   DWORD PTR DS:[EDI+EAX], 'WinE'
    	0x75, 0xF1,                               // JNZ   SHORT label1
    	0x8B, 0x74, 0x1F, 0x1C,                   // MOV   ESI, DWORD PTR DS:[EDI+EBX+1C]
    	0x01, 0xFE,                               // ADD   ESI, EDI
    	0x03, 0x3C, 0xAE,                         // ADD   EDI, DWORD PTR DS:[ESI+EBP*4]
    	0xFF, 0xD7,                               // CALL  EDI
    	0x58,                                     // POP   EAX (stack alignment)
    	0x58,                                     // POP   EAX (stack alignment)
    	0xC3                                      // RET
    };
    I will provide step by step code, using exception throwing (this code is used in a library I made few days ago).

    Code:
    int    iProcessId = 1337;
    IntPtr hHandle    = OpenProcess(ProcessAccessFlags.All, false, iProcessId);
    
    if (hHandle == IntPtr.Zero)
    	throw new ApplicationException("Cannot get process handle.");
    Here, we get a process handle with all access (for no further problem) and check if the call was successful.

    Code:
    IntPtr hAlloc = VirtualAllocEx(hHandle, IntPtr.Zero, (uint)asm.Length, AllocationType.Commit, MemoryProtection.ExecuteReadWrite);
    
    if (hAlloc == IntPtr.Zero)
    	throw new ApplicationException("Cannot allocate memory.");
    Now, we allocate some memory to put our shellcode in RWX (Read/Write/Execute) mode.

    Code:
    UIntPtr bytesWritten = UIntPtr.Zero;
    
    if (!WriteProcessMemory(hHandle, hAlloc, asm, (uint)asm.Length, out bytesWritten))
    	throw new ApplicationException("Cannot write process memory.");
    
    if (asm.Length != (int)bytesWritten)
    	throw new ApplicationException("Invalid written size.");
    We write process memory using our shellcode and then check if we have written the correct number of bytes.

    Code:
    uint   iThreadId = 0;
    IntPtr hThread   = CreateRemoteThread(hHandle, IntPtr.Zero, 0, hAlloc, IntPtr.Zero, 0, out iThreadId);
    
    if (hThread == IntPtr.Zero)
    	throw new ApplicationException("Cannot create and execute remote thread.");
    And then we create and execute a thread on our shellcode and the calc.exe should appear!

    Code:
    CloseHandle(hThread);
    CloseHandle(hHandle);
    And now, we close our handles.

    Instead of using complexes libraries, you can just use severals API to inject our own ASM code.
    But you cannot inject directly you ASM code, you have to get opcodes before that.

    Anyways, I hope this will be useful.

    [C#] ASM Injection (CreateRemoteThread)
  2. #2
    Frosttall's Avatar Active Member
    Reputation
    64
    Join Date
    Feb 2011
    Posts
    261
    Thanks G/R
    16/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice tutorial. +rep

    Originally Posted by Xartrick View Post
    Instead of using complexes libraries, you can just use severals API to inject our own ASM code.
    But you cannot inject directly you ASM code, you have to get opcodes before that.
    Here's the source for a pretty small Managed C++ Library in order to convert ASM-Instructions into opcodes.
    Multiupload.nl - upload your files to multiple file hosting sites!
    https://mega.co.nz/#!BwJzQR6S!VZHb0y...Q3UAbMb7JPk_mo
    Source: Forgot where I got it from


    P.S. Executing shellcode in WoW should be done via hooking a mainthread-function (like EndScene) instead of a remote-thread because especially the Lua-Engine is single-threaded and will lead to problems.
    Last edited by Frosttall; 07-12-2013 at 02:56 PM.

  3. #3
    ck298's Avatar Private
    Reputation
    1
    Join Date
    Jul 2013
    Posts
    4
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    you shold make the call from main thread or updata TLS at fs:[2c] and callback at [ebp+4]

  4. #4
    Xartrick's Avatar Active Member
    Reputation
    24
    Join Date
    May 2011
    Posts
    29
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Frosttall View Post
    Nice tutorial. +repHere's the source for a pretty small Managed C++ Library in order to convert ASM-Instructions into opcodes.
    Multiupload.nl - upload your files to multiple file hosting sites!
    https://mega.co.nz/#!BwJzQR6S!VZHb0y...Q3UAbMb7JPk_mo
    Source: Forgot where I got it from
    This library was made by Shynd.
    I already use it and it's easy to use, it use the same method as am I.

    Originally Posted by Frosttall View Post
    P.S. Executing shellcode in WoW should be done via hooking a mainthread-function (like EndScene) instead of a remote-thread because especially the Lua-Engine is single-threaded and will lead to problems.
    Oh, I didn't know that. I never reversed WoW, will do it for sure!

    Originally Posted by ck298 View Post
    you shold make the call from main thread or updata TLS at fs:[2c] and callback at [ebp+4]
    I will check this out, thanks for your advice.

  5. #5
    Seifer's Avatar Site Donator
    Reputation
    129
    Join Date
    Apr 2007
    Posts
    270
    Thanks G/R
    1/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Xartrick View Post
    This library was made by Shynd.
    Shynd wrote the managed wrapper for it iirc, the original dll (fasm.dll) is actually flat assembler.

  6. #6
    Xartrick's Avatar Active Member
    Reputation
    24
    Join Date
    May 2011
    Posts
    29
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Seifer View Post
    Shynd wrote the managed wrapper for it iirc, the original dll (fasm.dll) is actually flat assembler.
    Of course, it's a wrapper for FASM in .NET.

  7. #7
    zys924's Avatar Active Member
    Reputation
    20
    Join Date
    Nov 2009
    Posts
    113
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Anybody knows if there is a purely managed flat assembler?

  8. #8
    Jadd's Avatar 🐸
    Reputation
    1511
    Join Date
    May 2008
    Posts
    2,432
    Thanks G/R
    81/333
    Trade Feedback
    1 (100%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by zys924 View Post
    Anybody knows if there is a purely managed flat assembler?
    None that I know of, but you can simply wrap the exports from Shynd's lib in .NET. BlackMagic already does this for you, but if you don't want to use it simply take the export definitions.

    BlackMagic -- Managed Memory Manipulation
    https://github.com/tanis2000/babbot/...asmdll_managed

Similar Threads

  1. [Release] [C# DLL] iHook, EndScene ASM Injection!
    By -Ryuk- in forum WoW Memory Editing
    Replies: 142
    Last Post: 09-19-2022, 09:06 PM
  2. [C#] ASM Injection (SetThreadContext)
    By Xartrick in forum WoW Memory Editing
    Replies: 3
    Last Post: 07-19-2013, 04:33 PM
  3. [question] basic asm injection
    By abuckau907 in forum WoW Memory Editing
    Replies: 12
    Last Post: 03-07-2012, 05:38 AM
  4. About CTM via asm injection
    By N1ghtmaree in forum WoW Memory Editing
    Replies: 11
    Last Post: 08-08-2010, 10:57 AM
  5. Injecting ASM problems
    By lanman92 in forum WoW Memory Editing
    Replies: 33
    Last Post: 03-16-2009, 06:46 AM
All times are GMT -5. The time now is 11:06 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search