Valhalla Legends Forums Archive | .NET Platform | Re: [C#] Warden and Init()

AuthorMessageTime
Ribose
So I'm trying to call the initialization function in Warden, and it works, except it can't call what I've passed to it in the structure.
Code:
[code]
                        unsafe {
                            fixed (byte* module = local_module) {
...
                                #region Update References
                                Console.WriteLine("[WARDEN] Update...");
                                Console.WriteLine("[WARDEN] Update: Adjusting references to global variables...");
                               
                                int sorcLocation = Marshal.ReadInt32(new IntPtr(module + 0x08));
                                int destLocation = 0;
                                int limit = Marshal.ReadInt32(new IntPtr(module + 0x0C));
                                int adder = 0;
                                for (int counter = 0; counter < limit; counter++) {
                                    adder =
                                        ((Marshal.ReadByte(new IntPtr(module + sorcLocation)) << 8) |
                                         (Marshal.ReadByte(new IntPtr(module + sorcLocation + 1))));
                                    destLocation += adder;
                                    sorcLocation += 2;

                                    int oldAddress = Marshal.ReadInt32(new IntPtr(module + destLocation));
                                    if (oldAddress < local_module.Length && oldAddress > 0) {
                                        int newAddress = oldAddress + new IntPtr(module).ToInt32();
                                        Marshal.WriteInt32(new IntPtr(module + destLocation), newAddress);
                                    }
                                }

                                Console.WriteLine("[WARDEN] Update: Updating API library references...");
                                // this "cache" makes sure the GC does not eat my delegates until the end.
                                Dictionary<string, Delegate> delegateCache = new Dictionary<string, Delegate>();
                                int libCount = Marshal.ReadInt32(new IntPtr(module + 0x20));
                                for (int counter = 0; counter < libCount; counter++) {
                                    int procStart = Marshal.ReadInt32(new IntPtr(module + 0x1C)) + (counter * 8);
                                    string procLib = Marshal.PtrToStringAnsi(new IntPtr(module + Marshal.ReadInt32(new IntPtr(module + procStart))));
                                    int procOffset = Marshal.ReadInt32(new IntPtr(module + procStart + 4));
                                    Console.WriteLine("                 Library: " + procLib);
                                    IntPtr procModule = LoadLibraryA(procLib);
                                    int proc = Marshal.ReadInt32(new IntPtr(module +procOffset));
                                    do {
                                        if (proc > 0) {
                                            string procFunc = Marshal.PtrToStringAnsi(new IntPtr(module + proc));
                                            int procAddr = 0;
                                            MethodInfo procRedirector = typeof(ApiRedirector).GetMethod("my" + procFunc);
                                            Type procDelegate = typeof(ApiRedirector).GetNestedType("d" + procFunc);
                                            if (procRedirector == null || procDelegate == null) {
                                                Console.WriteLine("                   Function: " + procFunc + " @ NOT HANDLED");
                                            } else {
                                                delegateCache.Add(procFunc, Delegate.CreateDelegate(procDelegate, procRedirector));
                                                procAddr = Marshal.GetFunctionPointerForDelegate(delegateCache[procFunc]).ToInt32();
                                                Console.WriteLine("                   Function: " + procFunc + " @ MY " + procAddr);
                                            }
                                            Marshal.WriteInt32(new IntPtr(module + procOffset), procAddr);
                                        } else {
                                            proc &= 0x7FFFFFFF;
                                            Console.WriteLine("                   Ordinary: " + proc.ToString());
                                        }
                                        procOffset += 4;
                                        proc = Marshal.ReadInt32(new IntPtr(module + procOffset));
                                    } while (proc > 0);
                                    FreeLibrary(procModule);
                                }
                                #endregion

                                #region Initialize
                                Console.WriteLine("[WARDEN] Initialize...");
                                int pInit, D, B;
                                B = Marshal.ReadInt32(new IntPtr(module + 0x18));
                                D = 1 - B;
                                if (D > Marshal.ReadInt32(new IntPtr(module + 0x14)))
                                    throw new Exception("1 - *0x00000018 > *0x00000014.");
                                pInit = Marshal.ReadInt32(new IntPtr(module + 0x10));
                                pInit = Marshal.ReadInt32(new IntPtr(module + pInit + (D * 4)));
                                Console.WriteLine("[WARDEN] Initialize function: *0x" + pInit.ToString("X"));

                                delegateCache.Add("SendPacket", (Delegate) new fnSendPacket(SendPacket));
                                delegateCache.Add("CheckModule", (Delegate) new fnCheckModule(CheckModule));
                                delegateCache.Add("LoadModule", (Delegate) new fnLoadModule(ModuleLoad));
                                delegateCache.Add("AllocateMemory", (Delegate) new fnAllocateMemory(AllocateMemory));
                                delegateCache.Add("FreeMemory", (Delegate) new fnReleaseMemory(FreeMemory));
                                delegateCache.Add("SetRC4Data", (Delegate) new fnSetRC4Data(SetRC4Data));
                                delegateCache.Add("GetRC4Data", (Delegate) new fnGetRC4Data(GetRC4Data));

                                FuncList myFunctionList = new FuncList();
                                myFunctionList.fpSendPacket = Marshal.GetFunctionPointerForDelegate(delegateCache["SendPacket"]).ToInt32();
                                myFunctionList.fpCheckModule = Marshal.GetFunctionPointerForDelegate(delegateCache["CheckModule"]).ToInt32();
                                myFunctionList.fpLoadModule = Marshal.GetFunctionPointerForDelegate(delegateCache["LoadModule"]).ToInt32();
                                myFunctionList.fpAllocateMemory = Marshal.GetFunctionPointerForDelegate(delegateCache["AllocateMemory"]).ToInt32();
                                myFunctionList.fpReleaseMemory = Marshal.GetFunctionPointerForDelegate(delegateCache["FreeMemory"]).ToInt32();
                                myFunctionList.fpSetRC4Data = Marshal.GetFunctionPointerForDelegate(delegateCache["SetRC4Data"]).ToInt32();
                                myFunctionList.fpGetRC4Data = Marshal.GetFunctionPointerForDelegate(delegateCache["GetRC4Data"]).ToInt32();

                                Console.WriteLine("[WARDEN] Init()");
                                IntPtr myFuncList = Marshal.AllocHGlobal(sizeof(FuncList));
                                Marshal.StructureToPtr(myFunctionList, myFuncList, true);
                                FuncList* pFuncList = (FuncList*) myFuncList.ToPointer();
                                FuncList** ppFuncList = &pFuncList;
                                fnInitializeModule init = (fnInitializeModule) Marshal.GetDelegateForFunctionPointer(new IntPtr(pInit + module), typeof(fnInitializeModule));
                                WardenFuncList** ppWFuncList = init(ppFuncList);
                                Marshal.DestroyStructure(myFuncList, typeof(FuncList));
                                Marshal.FreeHGlobal(myFuncList);
                                #endregion
...
                            }
                        }
...
        private unsafe delegate WardenFuncList** fnInitializeModule(void* lpPtr2Table);

        private unsafe delegate void fnSendPacket(byte* pPacket, int dwSize);
        private unsafe delegate int fnCheckModule(byte* pModName, int _2);
        private unsafe delegate WardenFuncList** fnLoadModule(byte* pRC4Key, byte* pModule, int dwModSize);
        private unsafe delegate void* fnAllocateMemory(int dwSize);
        private unsafe delegate void fnReleaseMemory(void* lpMemory);
        private unsafe delegate void fnSetRC4Data(void* lpKeys, int dwSize);
        private unsafe delegate int fnGetRC4Data(void* lpBuffer, int* dwSize);

        [StructLayout(LayoutKind.Explicit, Size = 0x1C)]
        private struct FuncList {
            [FieldOffset(0x00)]
            public int fpSendPacket;
            [FieldOffset(0x04)]
            public int fpCheckModule;
            [FieldOffset(0x08)]
            public int fpLoadModule;
            [FieldOffset(0x0C)]
            public int fpAllocateMemory;
            [FieldOffset(0x10)]
            public int fpReleaseMemory;
            [FieldOffset(0x14)]
            public int fpSetRC4Data;
            [FieldOffset(0x18)]
            public int fpGetRC4Data;
        };

        private unsafe delegate void fnGenerateRC4Keys(WardenFuncList** ppFncList, void* lpData, int dwSize);
        private unsafe delegate void fnUnloadModule(WardenFuncList** ppFncList);
        private unsafe delegate void fnPacketHandler(WardenFuncList** ppFncList, byte* pPacket, int dwSize, int* dwBuffer);
        private unsafe delegate void fnTick(WardenFuncList** ppFncList, int _2); // _2 is sum dwOldTick - GetTickCount(); shit ..

        [StructLayout(LayoutKind.Explicit, Size = 0x10)]
        private struct WardenFuncList {
            [FieldOffset(0x00)]
            public int fpGenerateRC4Keys;
            [FieldOffset(0x04)]
            public int fpUnload;//0x04 - Before it frees everything it will call FuncList:fpSetRC4Data and store the RC4 key
            [FieldOffset(0x08)]
            public int fpPacketHandler;
            [FieldOffset(0x0C)]
            public int fpTick;
        };
...
        private unsafe void SendPacket(byte* pPacket, int length) {
            Console.WriteLine("         SendPacket(" + new IntPtr(pPacket).ToInt32() + ", " + length + ")");
            if (length < 1 || length > 5000)
                return;
            m_Response = new byte[length];
            fixed (byte* buffer = m_Response)
                for (int i = 0; i < length; i++)
                    *(buffer + i) = *(pPacket + i);
        }

        private unsafe int CheckModule(byte* pModule, int pKey) {
            Console.WriteLine("         CheckModule(" + new IntPtr(pModule).ToInt32() + ", " + pKey + ")");
            //'CheckModule = false '//Need to download
            //'CheckModule = true '//Don't need to download
            return 1;
        }

        private unsafe WardenFuncList** ModuleLoad(byte* pRC4Key, byte* pModule, int length) {
            Console.WriteLine("         ModuleLoad(" + new IntPtr(pRC4Key).ToInt32() + ", " + new IntPtr(pModule).ToInt32() + ", " + length + ")");
            //'ModuleLoad = 0 '//Need to download
            //'ModuleLoad = 1 '//Don't need to download
            return (WardenFuncList**) IntPtr.Zero.ToPointer();
        }

        private unsafe void* AllocateMemory(int length) {
            Console.WriteLine("         AllocateMemory(" + length + ")");
            return Marshal.AllocHGlobal(length).ToPointer();
        }

        private unsafe void FreeMemory(void* mem) {
            Console.WriteLine("         FreeMemory(" + new IntPtr(mem).ToInt32() + ")");
            Marshal.FreeHGlobal(new IntPtr(mem));
        }

        private unsafe void SetRC4Data(void* keys, int length) {
            Console.WriteLine("         SetRC4Data(" + new IntPtr(keys).ToInt32() + ", " + length + ")");
        }

        private unsafe int GetRC4Data(void* buffer, int* length) {
            Console.WriteLine("         SetRC4Data(" + new IntPtr(buffer).ToInt32() + ", " + *length + ")");
            //'GetRC4Data = 1 'got the keys already
            //'GetRC4Data = 0 'generate new keys
            int rc4 = m_RC4;
            m_RC4 = new IntPtr(buffer).ToInt32();
            return rc4;
        }
[/code]
I have this code, which successfully updates the variable references in the prepared .bin (as far as I can tell).

Then, it redirects the API references (all of them that the initialize function calls and some others, anyway) to the ApiRedirector class which contains d(apifunctionname) my(apifunctionname) pairs that output that they have been called and return to the function.
Example:
[code]
            public delegate int dGetCurrentProcessId();

            public static int myGetCurrentProcessId() {
                int r = GetCurrentProcessId();
                Console.WriteLine("         GetCurrentProcessId() = " + r);
                return r;
            }[/code]
Then it finds and calls the initialize function.

According to this output, it works, until the point that it tries to call AllocateMemory.
Output:
[quote][WARDEN] Request ID 0x0
[WARDEN] Module 4EB548D75368813F44D14D2E50FE46.mod found.
[WARDEN] Ready and prepared.
[WARDEN] Sending Decrypted:
0000   01                                                  .

[WARDEN] Request ID 0x5
[WARDEN] Data was not retrieved from Battle.net, reading from .bin instead...
[WARDEN] Update...
[WARDEN] Update: Adjusting references to global variables...
[WARDEN] Update: Updating API library references...
                 Library: KERNEL32.dll
                   Function: IsValidCodePage @ NOT HANDLED
                   Function: Sleep @ MY 3567778
                   Function: TlsFree @ MY 3567826
                   Function: TlsGetValue @ MY 3567874
                   Function: TlsSetValue @ MY 3567922
                   Function: RaiseException @ MY 3568354
                   Function: TlsAlloc @ MY 3568754
                   Function: GetProcAddress @ MY 3568802
                   Function: GetModuleHandleA @ MY 3568850
                   Function: GetVersionExA @ MY 3568898
                   Function: GetSystemInfo @ MY 3568946
                   Function: GetTickCount @ MY 3568994
                   Function: VirtualQuery @ MY 3569138
                   Function: QueryDosDeviceA @ MY 3569458
                   Function: CloseHandle @ MY 3569506
                   Function: GetCurrentProcess @ MY 3569554
                   Function: FreeLibrary @ MY 3569602
                   Function: DuplicateHandle @ MY 3569810
                   Function: LoadLibraryA @ MY 3570130
                   Function: GetProcessHeap @ MY 3570178
                   Function: HeapFree @ MY 3570226
                   Function: TerminateProcess @ MY 3570274
                   Function: UnhandledExceptionFilter @ MY 3570322
                   Function: SetUnhandledExceptionFilter @ MY 3570370
                   Function: QueryPerformanceCounter @ MY 3570418
                   Function: GetCurrentThreadId @ MY 3570466
                   Function: GetCurrentProcessId @ MY 3570514
                   Function: GetSystemTimeAsFileTime @ MY 3570562
                   Function: RtlUnwind @ MY 3570610
                 Library: USER32.dll
                   Function: ScrollWindowEx @ NOT HANDLED
                   Function: IsWindowEnabled @ NOT HANDLED
                   Function: CharUpperBuffA @ MY 3570658
                   Function: IsMenu @ NOT HANDLED
[WARDEN] Initialize...
[WARDEN] Initialize function: *0x5820
[WARDEN] Init()
         GetSystemTimeAsFileTime(61729376) = void
         GetCurrentProcessId() = 5792
         GetCurrentThreadId() = 5432
         GetTickCount() = 284644468
         QueryPerformanceCounter(61729368) = 1
         GetModuleHandle("kernel32.dll = 2088763392
         GetProcAddress(2088763392, "AddVectoredExceptionHandler") = 2090036218
         GetProcAddress(2088763392, "RemoveVectoredExceptionHandler") = 2090036326
         TlsAlloc() = 29
         TlsSetValue(29, 0) = 1
         TlsGetValue(29) = 0
A first chance exception of type 'System.AccessViolationException' occurred
[/quote]
Anyone have any ideas I can try?

Much of this code is from Ringo's code, and iago's wiki.

Edit: title
December 21, 2008, 10:23 PM
BreW
Perhaps the module likes __stdcalls
December 22, 2008, 1:43 AM
Ribose
[quote author=brew link=topic=17758.msg180920#msg180920 date=1229910234]
Perhaps the module likes __stdcalls
[/quote]
Can that be done in C#? (I'm not too sure it can.)
Besides, the API hijacks worked, and they are __fastcall, though that might be wrong.
December 22, 2008, 1:55 AM
BreW
Probably not.
Perhaps you should make a dll to the calling and callbacks in assembly, or something.
Later down the line if you want to call the module's 'exported' functions you'd have to do a thiscall, which wasn't supported by my compiler (MSVC6). Luckily I had the inline assembler directive (__asm) to work with.
December 22, 2008, 2:07 AM
Ribose
[quote author=brew link=topic=17758.msg180922#msg180922 date=1229911678]
Probably not.
Perhaps you should make a dll to the calling and callbacks in assembly, or something.
Later down the line if you want to call the module's 'exported' functions you'd have to do a thiscall, which wasn't supported by my compiler (MSVC6). Luckily I had the inline assembler directive (__asm) to work with.
[/quote]I really don't want to have to do that, but if anybody else has any extensive knowledge on how C# calls functions that could tell me why the module code isn't finding my functions, perhaps I don't have to.
December 22, 2008, 2:41 AM
Myndfyr
[quote author=Ribose link=topic=17758.msg180921#msg180921 date=1229910907]
[quote author=brew link=topic=17758.msg180920#msg180920 date=1229910234]
Perhaps the module likes __stdcalls
[/quote]
Can that be done in C#? (I'm not too sure it can.)
Besides, the API hijacks worked, and they are __fastcall, though that might be wrong.
[/quote]
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.unmanagedfunctionpointerattribute.aspx
December 22, 2008, 6:51 AM
Ribose
Specifying that the delegates are __stdcall with the line " [UnmanagedFunctionPointer(CallingConvention.StdCall)] " doesn't change the output.  Besides, I notice that the .StdCall is the default according to the enumeration's documentation.
December 22, 2008, 8:48 PM
Ribose
Interesting, I set the Init delegate to "[UnmanagedFunctionPointer(CallingConvention.ThisCall)]" and it worked, even though it was __fastcall (which the .Net framework says isn't supported).
December 24, 2008, 1:05 AM
Myndfyr
The framework can't support fastcall since it requires knowing the function binding, which it doesn't (because it's not getting the .obj file, just the .dll).  Thiscall, however, passes a this pointer through ECX, and if other parameters are passed normally, just might work.
December 24, 2008, 10:14 PM
Ribose
So this code is working pretty nicely... except that very often Visual Studio pops up with:
[quote]Reentrancy was detected
Message: Attempting to call into managed code without transitioning out first.  Do not attempt to run managed code inside low-level native extensibility points, such as the vectored exception handler, since doing so can cause corruption and data loss.[/quote]
With no explanation beyond and not pointing to any specific code and with an OK and Continue button.
Continue makes the message go away, then immediately re-appear.
OK makes breaks debugging execution, and when I hit Continue debugging, it goes back to the message (I have to stop or sometimes force close the program).
I'm 100% sure it has to do with the fact that I'm calling the native code (Warden's Init function, GenerateRC4Keys function, and HandlePacket function), and its calling functions in the C# or something.
I don't know how to get C# to either ignore this (because otherwise the code is working properly), or to have code that is not "re-entrant".
January 6, 2009, 1:37 AM
Myndfyr
You're providing managed callbacks into Warden right? 

You can turn off the MDA but you should look into it.

http://msdn.microsoft.com/en-us/library/ms172237.aspx
January 6, 2009, 7:18 AM
Ribose
[quote author=MyndFyre[vL] link=topic=17758.msg181045#msg181045 date=1231226322]
You're providing managed callbacks into Warden right?
[/quote]Yes.
[quote author=MyndFyre[vL] link=topic=17758.msg181045#msg181045 date=1231226322]
You can turn off the MDA but you should look into it.

http://msdn.microsoft.com/en-us/library/ms172237.aspx[/quote]
I've looked into it and it just has said the same thing over and over: "you are calling managed code from unmanaged code without transitioning out first". What does it mean to "transition out"?

If there's a problem with me calling the functions and the functions calling my functions, why then does the error pop up only after the calls complete successfully?

When I disable the MDA, at the point that the error would pop up (the calls to the three warden functions have completed, and the encrypted packet sent to Battle.net) the bot freezes. It would almost seem independent of the calls to the functions, except that it only occurs after the calls (connecting as WarCraft III, or an exception occurs before Warden's initialize() is called, the error/freeze is not triggered).

Why would the bot freeze when I attempt to do anything in the bot (it does not freeze until then), such as sending a message to Battle.net or connecting another profile to Battle.net, or disconnecting/losing connection to Battle.net, but not directly after calling one of the functions?

How can I go about making my code not be "reentrant" according to the debugger, or whatever code is causing the whole thing to freeze afterwards?

In fact, sometimes it works correctly if I execute it without Visual Studio at all, or if no breakpoints or other debugging breaking occurs.

Actually, after some more testing, it appears it works flawlessly when not being debugged in Visual Studio. I hope StarCraft doesn't get any exclusive new features that I have to debug anytime before I can figure out why its freezing unnecessarily in the debugger. :(
January 6, 2009, 8:42 PM
Myndfyr
[quote author=Ribose link=topic=17758.msg181051#msg181051 date=1231274571]
In fact, sometimes it works correctly if I execute it without Visual Studio at all, or if no breakpoints or other debugging breaking occurs.
[/quote]
That means you have a thread race occurring.  Not a big shocker that you have a reentrancy problem. :P

Follow the steps outlined in the MDA documentation.  You should walk the stack trace to try to identify the code that is calling the wrong code.

My guess is that you're running into an issue in which you have maybe a pointer to a delegate (and unmanaged-to-managed thunk pointer) and you're probably calling it from managed code somewhere.  Not sure how, but that's the best guess.
January 6, 2009, 11:47 PM
BreW
Or you could do the sensible thing, like pass back a nullsub to the module if/when it requests it (for me it was screwing up debugging):
[code]

void __stdcall nullsub(int p1, int p2) {

}

void __stdcall nullsub2(int p1) {

}

FARPROC WINAPI MyGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
AddChatEx(vbYellow, "Module getting address to 0x%08x!%s() ...", hModule, lpProcName);
if (!strcmp(lpProcName, "AddVectoredExceptionHandler")) {
return (FARPROC)nullsub;
} else if (!strcmp(lpProcName, "RemoveVectoredExceptionHandler")) {
return (FARPROC)nullsub2;
}

return GetProcAddress(hModule, lpProcName);
}


[/code]
January 7, 2009, 1:35 AM
Ribose
[quote author=MyndFyre[vL] link=topic=17758.msg181053#msg181053 date=1231285651]
[quote author=Ribose link=topic=17758.msg181051#msg181051 date=1231274571]
In fact, sometimes it works correctly if I execute it without Visual Studio at all, or if no breakpoints or other debugging breaking occurs.
[/quote]
That means you have a thread race occurring.  Not a big shocker that you have a reentrancy problem. :P

Follow the steps outlined in the MDA documentation.  You should walk the stack trace to try to identify the code that is calling the wrong code.

My guess is that you're running into an issue in which you have maybe a pointer to a delegate (and unmanaged-to-managed thunk pointer) and you're probably calling it from managed code somewhere.  Not sure how, but that's the best guess.
[/quote]
There is no stack trace for this exception, it's just sitting there pointing to no line of code, with no "View More Exception Detail" (or whatever it was...), and not caught by any try-catches I have.
A simple google image search shows pretty much what I have, except its the Reentrancy one (ew bmp):
[img]http://hoser.lander.ca/CodeDownload/LoadFromContext.bmp[/img]

I was pretty careful when I marshaled the pointers to/from delegates, and I'm not too sure what could be causing a race if the code is pretty much run on the thread the packets are handled on, and the WardenModule object shouldn't be being acted upon by any other threads (as far as I know anyway)... I'll double check these though.

I just looked at the output again:
[quote]
[WARDEN] Recieved Decrypted:
0000   00 3d 26 a9 c7 18 53 67  94 ba 27 4e 65 96 6f 5b    .=&©Ç.Sg.º'Ne.o[
0010   f9 87 6b 2a 59 8c 2c 6b  65 f4 ea 15 a8 f6 05 07    ù.k*Y.,keôê.¨ö..
0020   44 80 45 00 00                                      D.E..

[WARDEN] Request ID 0x0
[WARDEN] Module 3D26A9C718536794BA274E65966F5BF9.mod found.
[WARDEN] Initializing...
[WARDEN] Data was not retrieved from Battle.net, reading from .bin instead...
[WARDEN] Update...
[WARDEN] Update: Adjusting references to global variables...
[WARDEN] Update: Updating API library references...
                 Library: KERNEL32.dll
                   Function: WaitCommEvent @ NOT HANDLED
                   Function: Sleep @ MY 3568162
                   Function: TlsFree @ MY 3568210
                   Function: TlsGetValue @ MY 3568258
                   Function: TlsSetValue @ MY 3568306
                   Function: RaiseException @ MY 3568738
                   Function: TlsAlloc @ MY 3569138
                   Function: GetProcAddress @ MY 3569186
                   Function: GetModuleHandleA @ MY 3569234
                   Function: GetVersionExA @ MY 3569282
                   Function: GetSystemInfo @ MY 3569330
                   Function: GetTickCount @ MY 3569378
                   Function: VirtualQuery @ MY 3569522
                   Function: QueryDosDeviceA @ MY 3569842
                   Function: CloseHandle @ MY 3569890
                   Function: GetCurrentProcess @ MY 3569938
                   Function: FreeLibrary @ MY 3569986
                   Function: DuplicateHandle @ MY 3570194
                   Function: LoadLibraryA @ MY 3570514
                   Function: GetProcessHeap @ MY 3570562
                   Function: HeapFree @ MY 3570610
                   Function: TerminateProcess @ MY 3570658
                   Function: UnhandledExceptionFilter @ MY 3570706
                   Function: SetUnhandledExceptionFilter @ MY 3570754
                   Function: QueryPerformanceCounter @ MY 3570802
                   Function: GetCurrentThreadId @ MY 3570850
                   Function: GetCurrentProcessId @ MY 3570898
                   Function: GetSystemTimeAsFileTime @ MY 3570946
                   Function: RtlUnwind @ MY 3570994
                 Library: USER32.dll
                   Function: CharUpperBuffA @ MY 3571042
[WARDEN] Initialize...
[WARDEN] Initialize function: *0x6210
[WARDEN] Init()
         GetSystemTimeAsFileTime(64940344) = void
         GetCurrentProcessId() = 2728
         GetCurrentThreadId() = 4760
         GetTickCount() = 285434296
         QueryPerformanceCounter(64940336) = 1
         GetModuleHandle("kernel32.dll") = 2088763392
         GetProcAddress(2088763392, "AddVectoredExceptionHandler") = 2090036218
         GetProcAddress(2088763392, "RemoveVectoredExceptionHandler") = 2090036326
         TlsAlloc() = 29
         TlsSetValue(29, 0) = 1
         AllocateMemory(2020)
         AllocateMemory(52)
         GetSystemInfo(1994504) = void
         AllocateMemory(44)
         LoadLibraryA("kernel32.dll") = 2088763392
         GetProcAddress(2088763392, "CreateToolhelp32Snapshot") = 2089179935
         GetProcAddress(2088763392, "Module32First") = 2089177664
         GetProcAddress(2088763392, "Module32Next") = 2089178053
         GetVersionExA(64940184) = 1
[WARDEN] Module ready at 0x2339656.
[WARDEN] Sending Decrypted:
0000   01                                                  .

[WARDEN] Recieved Decrypted:
0000   05 fe e3 cf 3b ff 4b 01  83 90 0b 79 21 f7 0c 26    .þãÏ;ÿK....y!÷.&
0010   5e                                                  ^

[WARDEN] Request ID 0x5
[WARDEN] GenerateRC4Keys(p_WardenReturned, 15899308, 4)
         GetRC4Data(2295384, 520)
[WARDEN] PacketHandler(p_WardenReturned, 16563528, 17, 64942128)
         SendPacket(64940792, 21)
[WARDEN] Sending Decrypted:
0000   04 d0 6d 8f 9d c4 c6 bb  cd bd 95 b2 42 4b 7d 2a    .Ðm..ÄÆ»Í...BK}*
0010   1e 82 b7 98 0b                                      ..·..

[WARDEN] Recieved Decrypted:
0000   02 00 64 6a c6 4a 82 46  1d 22 47 4b 9d 6b 0b 9f    ..djÆJ.F."GK.k..
0010   c5 c5 4a 98 e3 80 98 14  de db f4 24 19 02 00 1f    ÅÅJ.ã...ÞÛô$....
0020   64 15 f8 02 f0 5c 5b 20  2f 02 40 18 32 97 90 1f    d.ø.ð\[ /.@.2...
0030   9a e6 fa 5b 6d 3e 58 5d  11 b9 32 00 00 24 64 5b    .æú[m>X]..2..$d[
0040   07 29 2d cc cc d1 f3 7d  ea f5 1a a8 03 a5 fb b1    .)-ÌÌÑó}êõ.¨.¥û±
0050   3d 67 7b 01 ad 7e 55 98  20 00 00 11 64 a8 81 24    =g{.­~U. ...d¨.$
0060   2c f8 ec 42 b1 22 14 ff  78 b6 9e a9 d3 76 e1 58    ,øìB±".ÿx¶.©ÓváX
0070   a2 a0 26 ec c4 20 50 00  00 10 64 18 e1 85 91 6a    ¢.&ìÄ P...d.á..j
0080   be 91 d8 57 f1 c4 61 d9  9b e7 d7 c0 19 4c 4d fb    ..ØWñÄaÙ.ç×À.LMû
0090   d2 a9 c7 60 d0 02 00 0c  77                          Ò©Ç`Ð...w

[WARDEN] Request ID 0x2
[WARDEN] PAGE_CHECK_A (0xFD)  Address: 0x21924  Length: 31
[WARDEN] PAGE_CHECK_A (0xFD)  Address: 0x32B9  Length: 36
[WARDEN] PAGE_CHECK_A (0xFD)  Address: 0x2098  Length: 17
[WARDEN] PAGE_CHECK_A (0xFD)  Address: 0x5020  Length: 16
[WARDEN] PAGE_CHECK_A (0xFD)  Address: 0x2D060  Length: 12
[WARDEN] Parsed 5 requests.
[WARDEN] Responding  Checksum: 0x3E4BBDF4  Length: 5
[WARDEN] Sending Decrypted:
0000   02 05 00 f4 bd 4b 3e 00  00 00 00 00                ...ô.K>.....

[WARDEN] Recieved Decrypted:
0000   02 00 64 d7 ef d0 a3 d0  ba fe 86 10 3e 4a 1d 38    ..d×ïУкþ..>J.8
0010   6a 18 da dd f7 d8 ce a5  f2 e6 a9 f8 d7 06 00 30    j.ÚÝ÷ØÎ¥òæ©ø×..0
0020   64 5d 82 cd 4d 24 9d 51  94 d9 cc 53 2c b9 7d be    d].ÍM$.Q.ÙÌS,.}.
0030   18 8a cf 3b 16 b5 ee 25  44 08 59 00 00 19 64 44    ..Ï;.µî%D.Y...dD
0040   67 e5 e4 a4 b9 9b eb 02  68 c1 08 0e 2d 49 0d 2d    gåä¤..ë.hÁ..-I.-
0050   26 aa eb af 19 ab 15 c0  8e 00 00 37 64 d2 04 30    &ªë¯.«.À...7dÒ.0
0060   75 d8 f2 d0 64 d5 d9 f5  d1 d8 78 f9 4f d1 82 bc    uØòÐdÕÙõÑØxùOÑ..
0070   c5 f9 99 83 5a 4c 30 00  00 16 64 fc 16 d6 e1 5f    Åù..ZL0...dü.Öá_
0080   16 9c b5 57 4b af e9 3c  16 c7 a2 1a 66 4c 56 cf    ..µWK¯é<.Ç¢.fLVÏ
0090   e4 8c 0c 3c 34 02 00 1f  77                          ä..<4...w

[WARDEN] Request ID 0x2
[WARDEN] PAGE_CHECK_A (0xFD)  Address: 0x6D7F8  Length: 48
[WARDEN] PAGE_CHECK_A (0xFD)  Address: 0x5908  Length: 25
[WARDEN] PAGE_CHECK_A (0xFD)  Address: 0x8EC0  Length: 55
[WARDEN] PAGE_CHECK_A (0xFD)  Address: 0x304C  Length: 22
[WARDEN] PAGE_CHECK_A (0xFD)  Address: 0x2343C  Length: 31
[WARDEN] Parsed 5 requests.
[WARDEN] Responding  Checksum: 0x3E4BBDF4  Length: 5
[WARDEN] Sending Decrypted:
0000   02 05 00 f4 bd 4b 3e 00  00 00 00 00                ...ô.K>.....
[/quote]and noticed "AddVectoredExceptionHandler" and "RemoveVectoredExceptionHandler". I noticed that those APIs are mentioned in the Reentrancy MDA page. Could this be a part of the problem?
January 7, 2009, 3:09 AM
BreW
So like, you totally just ignored my post.. which explains that those two apis it uses are part of the problem.....
January 7, 2009, 2:12 PM
Myndfyr
[quote author=brew link=topic=17758.msg181059#msg181059 date=1231337541]
So like, you totally just ignored my post.. which explains that those two apis it uses are part of the problem.....
[/quote]
Nevermind the fact that pretty much all your posts in the .net forum have historically been useless because you don't know about .net....

[quote author=Ribose link=topic=17758.msg181057#msg181057 date=1231297768]
There is no stack trace for this exception, it's just sitting there pointing to no line of code, with no "View More Exception Detail" (or whatever it was...), and not caught by any try-catches I have.
[/quote]
That's because an MDA isn't an exception.  It's a .NET-provided breakpoint.  You should still be able to look at the call stack window in the debugger:

[img]http://www.jinxbot.net/pub/stacktrace.png[/img]
January 7, 2009, 4:15 PM
BreW
[quote author=MyndFyre[vL] link=topic=17758.msg181060#msg181060 date=1231344925]
[quote author=brew link=topic=17758.msg181059#msg181059 date=1231337541]
So like, you totally just ignored my post.. which explains that those two apis it uses are part of the problem.....
[/quote]
Nevermind the fact that pretty much all your posts in the .net forum have historically been useless because you don't know about .net....
[/quote]

It has more to do with logic than .NET actually:

[quote author=brew link=topic=17758.msg181056#msg181056 date=1231292143]
...
if (!strcmp(lpProcName, "AddVectoredExceptionHandler")) {
return (FARPROC)nullsub;
} else if (!strcmp(lpProcName, "RemoveVectoredExceptionHandler")) {
return (FARPROC)nullsub2;
}
...
[/quote]

[quote author=Ribose link=topic=17758.msg181057#msg181057 date=1231297768]
and noticed "AddVectoredExceptionHandler" and "RemoveVectoredExceptionHandler". I noticed that those APIs are mentioned in the Reentrancy MDA page. Could this be a part of the problem?
[/quote]
January 7, 2009, 4:56 PM
Ribose
[quote author=brew link=topic=17758.msg181059#msg181059 date=1231337541]
So like, you totally just ignored my post.. which explains that those two apis it uses are part of the problem.....
[/quote]
uhh oh, sorry
[quote author=brew link=topic=17758.msg181056#msg181056 date=1231292143]
Or you could do the sensible thing, like pass back a nullsub to the module if/when it requests it (for me it was screwing up debugging):
[code]

void __stdcall nullsub(int p1, int p2) {

}

void __stdcall nullsub2(int p1) {

}

FARPROC WINAPI MyGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
AddChatEx(vbYellow, "Module getting address to 0x%08x!%s() ...", hModule, lpProcName);
if (!strcmp(lpProcName, "AddVectoredExceptionHandler")) {
return (FARPROC)nullsub;
} else if (!strcmp(lpProcName, "RemoveVectoredExceptionHandler")) {
return (FARPROC)nullsub2;
}

return GetProcAddress(hModule, lpProcName);
}
[/code]
[/quote]
Oh, I didn't look at it much, and didn't understand what you were getting at ("if/when it requests it" didn't tell me what you were getting at... you could have said that Add/RemoveVectoredExceptionHandler was the problem instead of just "it" :o).

Now reading it again, yeah, that does make sense... I already hijacked the GetProcAddress, so I guess I can hijack those two specific calls as well.

I just hijacked those two, but its getting to there and failing:
[quote]
        GetProcAddress(2088763392, "AddVectoredExceptionHandler") = MY 3611266
        GetProcAddress(2088763392, "RemoveVectoredExceptionHandler") = MY 3611314
        TlsAlloc() = 31
        TlsSetValue(31, 0) = 1
        AddVectoredExceptionHandler(64944284, 0) = 0
        TlsFree(31) = 1
A first chance exception of type 'System.AccessViolationException' occurred
[/quote]According to the page, AddVectoredExceptionHandler should return a valid pointer (as far as I can tell) to some handle...

@Myndfyre: when the MDA appears, the call stack window has been empty...

I just changed it so it gets its own ProcAddress again, and this time the MDA is pointing directly to the line:
[code]pp_WardenFunctionList = new IntPtr(init((MyFuncList**) pp_MyFuncList));[/code]
and does have a call stack, which is exactly as I would expect (I also enabled "View External Code" in the call stack window, which may have done it):
[code]
[Managed to Native Transition]
green arrow Felbot.exe!Felbot.Protocol.WardenModule.InitializeModule() Line 696 + 0x3a bytes C#
Felbot.exe!Felbot.Protocol.WardenModule.RecieveWarden(byte[] encrypted = {byte[37]}) Line 180 + 0x8 bytes C#
Felbot.exe!Felbot.Protocol.BattleNetPacketThread.Recieve_SID_WARDEN(byte[] data = {byte[37]}) Line 1306 + 0x10 bytes C#
Felbot.exe!Felbot.Protocol.BattleNetPacketThread.ParsePacket(MBNCSUtil.DataReader dataReader = {MBNCSUtil.BncsReader}) Line 282 + 0x4e bytes C#
Felbot.exe!Felbot.Protocol.BattleNetPacketThread.Socket_Recieve(int length = 41) Line 3004 + 0x2d bytes C#
Felbot.exe!Felbot.Protocol.PacketThread..ctor.AnonymousMethod() Line 114 + 0x21 bytes C#
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x66 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x6f bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes
[/code]
January 7, 2009, 5:21 PM

Search