views:

154

answers:

1

I would like to calculate how many bytes my function fills so that I can inject it into another process using CreateRemoteThread(). Once I know the number of bytes, I can write them into the remote process using the function's pointer. I have found an article online (see http://www.codeproject.com/KB/threads/winspy.aspx#section_3, chapter III) where they do the following in C++ :

// ThreadFunc
// Notice: - the code being injected;
//Return value: password length
static DWORD WINAPI ThreadFunc (INJDATA *pData)
{
//Code to be executed remotely
}
// This function marks the memory address after ThreadFunc.
static void AfterThreadFunc (void) {
}

Then they calculate the number of bytes ThreadFunc fills using :

const int cbCodeSize = ((LPBYTE) AfterThreadFunc - (LPBYTE) ThreadFunc);

Using cbCodeSize they allocate memory in the remote process for the injected ThreadFunc and write a copy of ThreadFunc to the allocated memory:

pCodeRemote = (PDWORD) VirtualAllocEx( hProcess, 0, cbCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE );       
if (pCodeRemote == NULL)
__leave;
WriteProcessMemory( hProcess, pCodeRemote, &ThreadFunc, cbCodeSize, &dwNumBytesXferred );

I would like to do this in C#. :) I have tried creating delegates, getting their pointers, and subtracting them like this:

    // Thread proc, to be used with Create*Thread
    public delegate int ThreadProc(InjectionData param);       
    //Function pointer 
    ThreadFuncDeleg = new ThreadProc(ThreadFunc);
    ThreadFuncPtr = Marshal.GetFunctionPointerForDelegate(ThreadFuncDeleg);
    //FunctionPointer
    AfterThreadFuncDeleg = new ThreadProc(AfterThreadFunc);
    IntPtr AfterThreadFuncDelegPtr= Marshal.GetFunctionPointerForDelegate(AfterThreadFuncDeleg);
    //Number of bytes
    int cbCodeSize = (AfterThreadFuncDelegPtr.ToInt32() - ThreadFuncPtr.ToInt32())*4 ;

It just does not seem right, as I get a static number no matter what I do with the code.
My question is, if possible, how does one calculate the number of bytes a function's code fills in C#?

Thank you in advance.

+7  A: 

I don't think it is possible due dynamic optimization and code generation in .NET. You can try to measure IL-code length but when you try to measure machine-depended code length in general case it will fail.

By 'fail' I mean you can't get correct size that provide any meaning by using this technique dynamically.

Of course you can go with finding how NGEN, JIT compile works, pdb structure and try to measure. You can determine size of your code by exploring generated machine code in VS for example.

How to see the Assembly code generated by the JIT using Visual Studio


If you really need to determine size, start with NET Internals and Code Injection / NET Internals and Native Compiling but I can't imagine why you ever want it.

Be aware all internals about how JIT works exactly is subject to change so depending solution can be broken by any future version of .NET.


If you want to stick with IL: check Profiling Interfaces (CLR Profiling API), and a bit old articles: Rewrite MSIL Code on the Fly with the .NET Framework Profiling API and No Code Can Hide from the Profiling API in the .NET Framework 2.0. There are also some topics about CLR Profiling API here on SO.

But simplest way to explore assembly is Reflection API, you want MethodBody there. So you can check Length of MethodBody.GetILAsByteArray and you'll find method length in IL-commands.

Nick Martyshchenko
+1. Additionally, the CLR is free to take a contiguous C# function and JIT it to multiple disparate native code ranges.
Chris Schmich
Thank you so much for the comprehensive answer.
prettyCode
@prettyCode, glad to help you :)
Nick Martyshchenko