Author | Message | Time |
---|---|---|
Ringo | Hey I got bored, so I started porting iagos module preperation code from here: http://www.skullsecurity.org/wiki/index.php/Warden_Modules#Preperation I havent spent much time on this yet, so i'm still alittle unsure of a few things. Mainly, how do you calculate the base address of the function with in a given warden module, for handleing the packets? I noticed in iagos notes, hes talked of Maive_HandleWardenPacket() Should these function tables be generated when loading the module, or does the module its self allocate the memory for them? http://www.skullsecurity.org/wiki/index.php/My_notes "WardenFunctionList @ WardenUnknownPtr1" So far i'm able to prep the module, load it into memory and initialize it. Ive noticed when I do this, the function table I pass to it, get's a few callbacks to allocate memory. I haven't looked at these memory spaces yet, but are any of them a list of exportable warden function address'? Basicly, what i'm wanting to do, is load the module, pass it the 1st request(0x05) and get the responce(0x04) and the new RC4 keys, then unload it. Heres the output I currently have: (Code is below) [code] PrepareModule() Allocated 49152 (0xC000) bytes for new module Copying code sections to module. Adjusting references to global variables... Updating API library references.. Lib: KERNEL32.dll Function: Sleep Function: TlsGetValue Function: TlsSetValue Function: RaiseException Function: GetProcAddress Function: GetModuleHandleA Function: TlsAlloc Function: TlsFree Function: GetVersionExA Function: VirtualQuery Function: QueryDosDeviceA Function: GetTickCount Function: GetSystemInfo Function: GetCurrentProcess Function: LoadLibraryA Function: DuplicateHandle Function: CloseHandle Function: FreeLibrary Function: GetProcessHeap Function: HeapFree Function: TerminateProcess Function: UnhandledExceptionFilter Function: SetUnhandledExceptionFilter Function: QueryPerformanceCounter Function: GetCurrentThreadId Function: GetCurrentProcessId Function: GetSystemTimeAsFileTime Function: RtlUnwind Lib: USER32.dll Function: CharUpperBuffA Function: DestroyIcon Function: RegisterClassA Successfully mapped Warden Module to 0x3467678 InitializeWarden() Initialize Function is mapped at 0x346A858 Calling Initialize function and passing my callback function table Warden.AllocMemory() 2020 Warden.AllocMemory() 52 Warden.AllocMemory() 44 [/code] You can see it allocates 2020 bytes, 52 bytes and 44 bytes -- are thses possibly some exportable functions? I noticed I had to allocate the memory my self, and return it to the module, other wise it gets stuck. (or w/e) Here's the visual bitch 6.0 code, for anyone whos interested in this: (Yes, it's a hell of a mess atm) [code] Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal numbytes As Long) Private Declare Function LoadLibraryA Lib "kernel32" (ByVal strFilePath As String) As Long Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long Private Declare Sub CallFunc Lib "Warden" Alias "#2" (ByVal Address As Long, ByVal dwParam As Long) Private Declare Function AllocMem Lib "Warden" Alias "#1" (ByVal dwSize As Long) As Long Private Declare Sub FreeMem Lib "Warden" Alias "#3" (ByVal dwMem As Long) Public Function PrepareModule(ByRef pModule As Long) As Long Debug.Print "PrepareModule()" Dim dwModuleSize As Long Dim pNewModule As Long Dim hMem As Long dwModuleSize = getInteger(pModule, &H0) hMem = GlobalAlloc(0, dwModuleSize) pNewModule = GlobalLock(hMem) Debug.Print " Allocated " & dwModuleSize & " (0x" & Hex(dwModuleSize) & ") bytes for new module" Call CopyMemory(ByVal pNewModule, ByVal pModule, 40) Dim dwSrcLocation As Long Dim dwDestLocation As Long Dim dwLimit As Long dwSrcLocation = &H28 + (getInteger(pNewModule, &H24) * 12) dwDestLocation = getInteger(pModule, &H28) dwLimit = getInteger(pModule, &H0) Dim bSkip As Boolean Debug.Print " Copying code sections to module." While (dwDestLocation < dwLimit) Dim dwCount As Long Call CopyMemory(ByVal VarPtr(dwCount), ByVal pModule + dwSrcLocation, 1) Call CopyMemory(ByVal VarPtr(dwCount) + 1, ByVal pModule + dwSrcLocation + 1, 1) dwSrcLocation = dwSrcLocation + 2 If (bSkip = False) Then Call CopyMemory(ByVal pNewModule + dwDestLocation, ByVal pModule + dwSrcLocation, dwCount) dwSrcLocation = dwSrcLocation + dwCount End If bSkip = Not bSkip dwDestLocation = dwDestLocation + dwCount Wend Debug.Print " Adjusting references to global variables..." dwSrcLocation = getInteger(pModule, 8) dwDestLocation = 0 Dim i As Long Dim lng0x0C As Long Dim lngTest As Long Call CopyMemory(lng0x0C, ByVal pNewModule + &HC, 4) While (i < lng0x0C) Call CopyMemory(lngTest, ByVal pNewModule + dwSrcLocation, 1) lngTest = lngTest And &HFF& Call CopyMemory(ByVal VarPtr(lngTest) + 0, ByVal pNewModule + dwSrcLocation + 1, 1) Call CopyMemory(ByVal VarPtr(lngTest) + 1, ByVal pNewModule + dwSrcLocation, 1) dwDestLocation = dwDestLocation + lngTest dwSrcLocation = dwSrcLocation + 2 Call insertInteger(pNewModule, dwDestLocation, getInteger(pNewModule, dwDestLocation) + pNewModule) i = i + 1 Wend Debug.Print " Updating API library references.." dwLimit = getInteger(pNewModule, &H20) Dim dwProcStart As Long Dim szLib As String Dim dwProcOffset As Long Dim hModule As Long Dim dwProc As Long Dim szFunc As String For i = 0 To dwLimit - 1 dwProcStart = getInteger(pNewModule, &H1C) + (i * 8) szLib = GetSTRING(pNewModule + getInteger(pNewModule, dwProcStart)) dwProcOffset = getInteger(pNewModule, dwProcStart + 4) Debug.Print " Lib: " & szLib hModule = LoadLibraryA(szLib) dwProc = getInteger(pNewModule, dwProcOffset) While dwProc If (dwProc > 0) Then szFunc = GetSTRING(pNewModule + dwProc) Debug.Print " Function: " & szFunc Call insertInteger(pNewModule, dwProcOffset, GetProcAddress(hModule, szFunc)) Else dwProc = dwProc And &H7FFFFFFF Debug.Print " Ordinary: 0x" & Hex(dwProc) End If dwProcOffset = dwProcOffset + 4 dwProc = getInteger(pNewModule, dwProcOffset) Wend Next i Debug.Print " Successfully mapped Warden Module to 0x" & Hex(pNewModule) PrepareModule = pNewModule End Function Public Function InitializeWarden(ByRef pModule As Long) As Boolean Debug.Print "InitializeWarden()" Dim ECX As Long Dim EDX As Long Dim EBP As Long EBP = getInteger(pModule, &H18) EDX = 1 - EBP If (EDX > getInteger(pModule, &H14)) Then Exit Function ECX = getInteger(pModule, &H10) 'offsetWardenSetup ECX = getInteger(pModule, ECX + (EDX * 4)) + pModule Debug.Print " Initialize Function is mapped at 0x" & Hex(ECX) Dim F(6) As Long F(0) = Addr2Ptr(AddressOf SendPacket) F(1) = Addr2Ptr(AddressOf LoadModule) F(2) = 0& F(3) = Addr2Ptr(AddressOf AllocMemory) F(4) = Addr2Ptr(AddressOf FreeMemory) F(5) = Addr2Ptr(AddressOf SetRC4Data) F(6) = Addr2Ptr(AddressOf GetRC4Data) Debug.Print " Calling Initialize function and passing my callback function table" Call CallFunc(ECX, VarPtr(F(0))) InitializeWarden = True End Function Private Sub SendPacket(ByVal pPacket As Byte, ByVal dwSize As Long) Debug.Print "Warden.SendPacket() " & dwSize End Sub Private Sub LoadModule(ByVal A As Long, ByVal B As Long) Debug.Print "Warden.LoadModule() " & A & "/" & B End Sub Private Function AllocMemory(ByVal dwSize As Long) As Long AllocMemory = AllocMem(dwSize) Debug.Print "Warden.AllocMemory() " & dwSize End Function Private Sub FreeMemory(ByVal dwMemory As Long) Call FreeMem(dwMemory) Debug.Print "Warden.FreeMemory() " & dwMemory End Sub Private Sub SetRC4Data(ByVal lpKeys As Long, ByVal dwSize As Long) Debug.Print "Warden.SetRC4Data() " & lpKeys & "/" & dwSize End Sub Private Sub GetRC4Data(ByVal lpBuffer As Long, ByVal dwSize As Long) Debug.Print "Warden.GetRC4Data() " & lpBuffer & "/" & dwSize End Sub Private Function getInteger(ByRef bArray As Long, ByVal dwLocation As Long) As Long Call CopyMemory(getInteger, ByVal bArray + dwLocation, 4) End Function Private Sub insertInteger(ByRef bArray As Long, ByVal dwLocation As Long, ByVal dwValue As Long) Call CopyMemory(ByVal bArray + dwLocation, dwValue, 4) End Sub Private Function GetSTRING(ByRef bArray As Long) As String Dim bTest As Byte Dim i As Long Do Call CopyMemory(bTest, ByVal bArray + i, 1) If (bTest = 0) Then If (i = 0) Then Exit Function GetSTRING = String(i, 0) Call CopyMemory(ByVal GetSTRING, ByVal bArray, i) Exit Function End If i = i + 1 Loop End Function Private Function Addr2Ptr(ByVal lngAddr As Long) As Long Addr2Ptr = lngAddr End Function [/code] And heres the functions I compiled to a DLL to mainly call the init function, since its __fastcall and a bitch to call from a vb class: [code] typedef VOID (__fastcall *Function4)(DWORD* lpPtr); DllExport VOID __stdcall CallFunc(DWORD Func, DWORD Value) { Function4 test = (Function4)Func; DWORD dwTable = Value; test(&dwTable); return; } DllExport LPVOID __stdcall AllocMem(DWORD dwSize) { return malloc(dwSize); } DllExport VOID __stdcall FreeMem(LPVOID lpMemory) { free(lpMemory); } [/code] PrepareModule() takes the memory address of the module after its decrypted/decompressed etc, and returns an address of the preped module. Any ideas? thx in advance! | December 4, 2008, 6:50 AM |
Ringo | duh, silly me -- the initialize function returns the address of the 1st allocated block of memory, and it says in iagos notes, the modules export functions are in there. However, when I try call the handlepacket function, the module crashs and takes down vb with it :p The return data in the address the init function returns looks like this: [code] 00000 40 F1 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 @............... [/code] From the 1st pointer in that address space, I get somthing like: [code] 00000 E0 8F 1D 00 20 87 1D 00 00 7B 1D 00 A0 8D 1D 00 .... ....{...... [/code] In iagos notes, it says that offset 0x08 should be the handlepacket function, and when I go to that address in the module with IDA, it looks pretty much like it is. How ever, when I pass it 3 params, it crashs at offset 0x2C into the function :( Does anyone know if the params I pass to it, are the same as the default module, and how im ment to be passing it? It say's the params are, packet data, lengh of data, orginal data. Also, is it possible to just load a variable module, init it, and pass it the data, or do I have to load the default module 1st or somthing? And does the variable module decrypt the packets, or am I ment to do that? atm, ive just pass'ed it two null buffers and got nothing but crashs. Just wundering if anyone else has already done this, or can enlighten me? The fun is drying up :( I'm calling the function like so: [code] typedef int (__stdcall *SCFunc3)(DWORD* PacketData, DWORD Length, DWORD* ptrOriginalData); DllExport int __stdcall CallFuncS3(DWORD Func, DWORD* PacketData, DWORD Length, DWORD* ptrOriginalData) { SCFunc3 testS3 = (SCFunc3)Func; return testS3(PacketData, Length, ptrOriginalData); } [/code] /edit nm, duh at me again, I wasnt calling it right. | December 5, 2008, 2:50 AM |