TibiaSock - funkcja WaitForSingleObject

0

Witam, od jakiegoś czasu męczę się i szukam rozwiązania. Jak na razie znalazłem co nie tak działa.
Strona projektu TibiaSock: http://code.google.com/p/tibiasock/
Kod dllmain.cpp DLLki o nazwie "Tibiasock.dll":

//Tibiasock.dll by DarkstaR
//Special thanks to the authors of the following pages:

#include <windows.h>

#define OUTGOINGDATASTREAM 0x0828A08
#define OUTGOINGDATALEN 0x09B4894
#define SENDOUTGOINGPACKET 0x04FBA80

#define INCOMINGDATASTREAM 0x09B4880
#define PARSERFUNC 0x045d3f0

/* PEB & TIB */
DWORD GetThreadInfoBlockPointer()
{
	DWORD ThreadInfoBlock;
	__asm
	{
		MOV EAX, FS:[0x18]
		MOV [ThreadInfoBlock], EAX
	}
	return ThreadInfoBlock;
}
DWORD GetProcessImageBase(HANDLE process)
{
	DWORD ThreadInfoBlock = GetThreadInfoBlockPointer();
	DWORD ProcessEnviromentBlock, ImageBase;

	ReadProcessMemory(process, (LPVOID)(ThreadInfoBlock + 0x30), &ProcessEnviromentBlock, 4, NULL);
	ReadProcessMemory(process, (LPVOID)(ProcessEnviromentBlock + 0x8), &ImageBase, 4, NULL);
	return ImageBase;
}
DWORD GetProcessMainThreadId(HANDLE process)
{
	DWORD ThreadInfoBlock = GetThreadInfoBlockPointer();
	DWORD MainThreadId;

	ReadProcessMemory(process, (LPVOID)(ThreadInfoBlock + 0x24), &MainThreadId, 4, NULL);
	return MainThreadId;
}

/* THREADS */
HANDLE OpenAndSuspendThread(DWORD threadID)
{
	HANDLE thread = OpenThread((THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_SET_CONTEXT), false, threadID);
	SuspendThread(thread);
	return thread;
}
void ResumeAndCloseThread(HANDLE thread)
{
	ResumeThread(thread);
	CloseHandle(thread);
}
void ExecuteRemoteCode(HANDLE process, LPVOID codeAddress, LPVOID arg)
{
	HANDLE WorkThread = CreateRemoteThread(process, NULL, NULL, (LPTHREAD_START_ROUTINE)codeAddress, arg, NULL, NULL);
	WaitForSingleObject(WorkThread, INFINITE);
	CloseHandle(WorkThread);
}

/* MAIN CODE */
DWORD Rebase(DWORD address, DWORD base)
{
	return (DWORD)(((int)address - (int)0x400000) + (int)base);
}
/* To Server */
BYTE* CreateOutgoingBuffer(BYTE* dataBuffer, int length)
{
	BYTE actualBuffer[1024];
	ZeroMemory((LPVOID)actualBuffer, 8);
	memcpy((LPVOID)&actualBuffer[8], (LPVOID)dataBuffer, length-8);
	return actualBuffer;

}

void SendPacketToServerEx(HANDLE process, BYTE* dataBuffer, int length, DWORD SendStreamData, DWORD SendStreamLength, DWORD SendPacketCall)
{
	DWORD MainThreadId = GetProcessMainThreadId(process);
	HANDLE MainThread = OpenAndSuspendThread(MainThreadId);

	int OldLength;
	BYTE OldData[1024];
	ReadProcessMemory(process, (LPVOID)SendStreamLength, &OldLength, 4, NULL);
	ReadProcessMemory(process, (LPVOID)SendStreamData, OldData, OldLength, NULL);

	length += 8;
	BYTE* actualBuffer = CreateOutgoingBuffer(dataBuffer, length);
	WriteProcessMemory(process, (LPVOID)SendStreamLength, &length, 4, NULL);
	WriteProcessMemory(process, (LPVOID)SendStreamData, actualBuffer, length, NULL);

	ExecuteRemoteCode(process, (LPVOID)SendPacketCall, (LPVOID)1);

	WriteProcessMemory(process, (LPVOID)SendStreamLength, &OldLength, 4, NULL);
	WriteProcessMemory(process, (LPVOID)SendStreamData, OldData, OldLength, NULL);

	ResumeAndCloseThread(MainThread);
}
void SendPacketToServer(HANDLE process, BYTE* dataBuffer, int length)
{
	DWORD ImageBase = GetProcessImageBase(process);
	DWORD SendStreamData = Rebase(OUTGOINGDATASTREAM, ImageBase);
	DWORD SendStreamLength = Rebase(OUTGOINGDATALEN, ImageBase);
	DWORD SendPacketCall = Rebase(SENDOUTGOINGPACKET, ImageBase);
	SendPacketToServerEx(process, dataBuffer, length, SendStreamData, SendStreamLength, SendPacketCall);
}

/* To Client */
void WriteIncomingBuffer(HANDLE process, DWORD recvStream, BYTE* data, int length, int position)
{
	DWORD DataPointer;
	WriteProcessMemory(process, (LPVOID)(recvStream + 4), &length, 4, NULL);
	WriteProcessMemory(process, (LPVOID)(recvStream + 8), &position, 4, NULL);
	
	ReadProcessMemory(process, (LPVOID)recvStream, &DataPointer, 4, NULL);
	WriteProcessMemory(process, (LPVOID)DataPointer, data, length, NULL);
}
LPVOID CreateRemoteBuffer(HANDLE process, BYTE* dataBuffer, int length)
{
	LPVOID RemoteBufferPointer = VirtualAllocEx(process, NULL, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(process, RemoteBufferPointer, dataBuffer, length, NULL);
	return RemoteBufferPointer;
}

void SendPacketToClientEx(HANDLE process, BYTE* dataBuffer, int length, DWORD RecvStream, DWORD ParserCall)
{
	DWORD MainThreadId = GetProcessMainThreadId(process);
	HANDLE MainThread = OpenAndSuspendThread(MainThreadId);

	DWORD DataPointer;
	int OldLength, OldPosition;
	BYTE OldDataBuffer[4096];
	ReadProcessMemory(process, (LPVOID)(RecvStream + 4), &OldLength, 4, NULL);
	ReadProcessMemory(process, (LPVOID)(RecvStream + 8), &OldPosition, 4, NULL);
	ReadProcessMemory(process, (LPVOID)RecvStream, &DataPointer, 4, NULL);
	ReadProcessMemory(process, (LPVOID)DataPointer, OldDataBuffer, OldLength, NULL);

	WriteIncomingBuffer(process, RecvStream, dataBuffer, length, 0); 
	
	BYTE CodeCave[10] = {0xB8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xC3}; //MOV EAX, <DWORD> | CALL EAX | RETN
	memcpy(&CodeCave[1], &ParserCall, 4);
	LPVOID CodeCavePointer = CreateRemoteBuffer(process, CodeCave, 10);

	ExecuteRemoteCode(process, CodeCavePointer, (LPVOID)0);

	VirtualFreeEx(process, CodeCavePointer, 10, MEM_RELEASE);
	WriteIncomingBuffer(process, RecvStream, OldDataBuffer, OldLength, OldPosition); 

	ResumeAndCloseThread(MainThread);
}
void SendPacketToClient(HANDLE process, BYTE* dataBuffer, int length)
{
	DWORD ImageBase = GetProcessImageBase(process);
	DWORD RecvStream = Rebase(INCOMINGDATASTREAM, ImageBase);
	DWORD ParserCall = Rebase(PARSERFUNC, ImageBase);
	SendPacketToClientEx(process, dataBuffer, length, RecvStream, ParserCall);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
	return TRUE;
}

Kod programu głównego:

#include <iostream>
#include <tchar.h>
#include <windows.h>
#include "Packet.h"
#define DESIRED_ACCESS PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ

using namespace std;

typedef void (*_SendPacket)(HANDLE process, BYTE* dataBuffer, int length);

DWORD FindProcessByWindowName(char* windowName)
{
	DWORD procID = NULL;
	HWND window = FindWindowA(NULL, windowName);

	if (window)
		GetWindowThreadProcessId(window, &procID);

	return procID;
}

int _tmain(int argc, _TCHAR* argv[])
{
	_SendPacket SendPacketToServer;
	_SendPacket SendPacketToClient;
	HINSTANCE TibiaSockLib = LoadLibraryA("TibiaSock.dll");
	SendPacketToServer = (_SendPacket)GetProcAddress(TibiaSockLib, "SendPacketToServer");
	SendPacketToClient = (_SendPacket)GetProcAddress(TibiaSockLib, "SendPacketToClient");


	WORD procID = NULL;
	while (!procID)
	{
		system("Cls");
		cout << "Please start Tibia and login to begin the test." << endl;
		system("Pause");
		procID = FindProcessByWindowName("Tibia");
	}

	HANDLE process = OpenProcess(DESIRED_ACCESS, false, procID);

	for (int i = 0; i < 1000; i++)
	{
		srand(GetTickCount());

		Packet* p = new Packet();
		p->AddByte(0x96);
		p->AddByte(0x01);
		p->AddString("Testing OI");
		SendPacketToServer(process, p->GetRawPacket(), p->GetRawSize());
		delete p;

		p = new Packet();
		p->AddByte(0xB4);
		p->AddByte(0x11);
		p->AddString("Testing Incoming Injection");
		SendPacketToClient(process, p->GetRawPacket(), p->GetRawSize());
		delete p;

		Sleep(rand() % 900 + 700);
	}

	CloseHandle(process);
	return 0;
}

Kod wywala na

WaitForSingleObject
w DLL-ce w funkcji
void ExecuteRemoteCode(HANDLE process, LPVOID codeAddress, LPVOID arg)
. Sprawdzałem wszystko po kolei, tzn: po każdej linijce kodu wyświetlało coś w konsoli. Uchwyt w DLL-ce
WorkThread
dostaje to co musi (sprawdzałem IFem czy nie jest NULL lub czy 0x00000000). Adresy w
OUTGOINGDATASTREAM
itd są sprawne. Klient Tibii (dowolnie jakiej) crashuje się, natomiast program główny ani DLL nie.
Jakieś pomysły ? Poprawki?

0
BYTE* CreateOutgoingBuffer(BYTE* dataBuffer, int length)
{
    BYTE actualBuffer[1024];
    ...

    return actualBuffer;
}

Hmm...

0

Jak pisałem wcześniej, wciąż wywala przy: WaitForSingleObject(WorkThread, INFINITE) w funkcji void ExecuteRemoteCode(HANDLE process, LPVOID codeAddress, LPVOID arg) w DLLce. Uchwyt WorkThread dostaje 0x000000B4 (teraz sprawdziłem ponownie i dostał 0x000000AC)

0

Jak poprawiłeś tamtą funkcję?

0

dllmain.cpp wygląda tak:

//Tibiasock.dll by DarkstaR
//Special thanks to the authors of the following pages:

#include <windows.h>
#include <iostream>

#define OUTGOINGDATASTREAM 0x799080
#define OUTGOINGDATALEN 0x7998A8
#define SENDOUTGOINGPACKET 0x4F8E40

#define INCOMINGDATASTREAM 0x7998AC
#define PARSERFUNC 0x45C370

/* PEB & TIB */
DWORD GetThreadInfoBlockPointer()
{
    DWORD ThreadInfoBlock;
    __asm
    {
        MOV EAX, FS:[0x18]
            MOV[ThreadInfoBlock], EAX
    }
    return ThreadInfoBlock;
}
DWORD GetProcessImageBase(HANDLE process)
{
    DWORD ThreadInfoBlock = GetThreadInfoBlockPointer();
    DWORD ProcessEnviromentBlock, ImageBase;

    ReadProcessMemory(process, (LPVOID)(ThreadInfoBlock + 0x30), &ProcessEnviromentBlock, 4, NULL);
    ReadProcessMemory(process, (LPVOID)(ProcessEnviromentBlock + 0x8), &ImageBase, 4, NULL);
    return ImageBase;
}
DWORD GetProcessMainThreadId(HANDLE process)
{
    DWORD ThreadInfoBlock = GetThreadInfoBlockPointer();
    DWORD MainThreadId;

    ReadProcessMemory(process, (LPVOID)(ThreadInfoBlock + 0x24), &MainThreadId, 4, NULL);
    return MainThreadId;
}

/* THREADS */
HANDLE OpenAndSuspendThread(DWORD threadID)
{
    HANDLE thread = OpenThread((THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_SET_CONTEXT), false, threadID);
    SuspendThread(thread);
    return thread;
}
void ResumeAndCloseThread(HANDLE thread)
{
    ResumeThread(thread);
    CloseHandle(thread);
}
void ExecuteRemoteCode(HANDLE process, LPVOID codeAddress, LPVOID arg)
{
    std::cout << 3 << std::endl;
    HANDLE WorkThread = CreateRemoteThread(process, NULL, NULL, (LPTHREAD_START_ROUTINE)codeAddress, arg, NULL, NULL);
    std::cout << WorkThread << std::endl;
    std::cout << 3 << std::endl;
    WaitForSingleObject(WorkThread, INFINITE);
    std::cout << 3 << std::endl;
    CloseHandle(WorkThread);
    std::cout << 3 << std::endl;
}

/* MAIN CODE */
DWORD Rebase(DWORD address, DWORD base)
{
    return (DWORD)(((int)address - (int)0x400000) + (int)base);
}
/* To Server */
BYTE CreateOutgoingBuffer(BYTE* dataBuffer, int length)
{
    BYTE actualBuffer[1024];
    ZeroMemory((LPVOID)actualBuffer, 8);
    memcpy((LPVOID)&actualBuffer[8], (LPVOID)dataBuffer, length - 8);
    return *actualBuffer;
}

void SendPacketToServerEx(HANDLE process, BYTE* dataBuffer, int length, DWORD SendStreamData, DWORD SendStreamLength, DWORD SendPacketCall)
{
    DWORD MainThreadId = GetProcessMainThreadId(process);
    HANDLE MainThread = OpenAndSuspendThread(MainThreadId);

    int OldLength;
    BYTE OldData[1024];
    ReadProcessMemory(process, (LPVOID)SendStreamLength, &OldLength, 4, NULL);
    ReadProcessMemory(process, (LPVOID)SendStreamData, OldData, OldLength, NULL);

    length += 8;
    BYTE actualBuffer = CreateOutgoingBuffer(dataBuffer, length);
    WriteProcessMemory(process, (LPVOID)SendStreamLength, &length, 4, NULL);
    WriteProcessMemory(process, (LPVOID)SendStreamData, &actualBuffer, length, NULL);

    ExecuteRemoteCode(process, (LPVOID)SendPacketCall, (LPVOID)1);

    WriteProcessMemory(process, (LPVOID)SendStreamLength, &OldLength, 4, NULL);
    WriteProcessMemory(process, (LPVOID)SendStreamData, OldData, OldLength, NULL);

    ResumeAndCloseThread(MainThread);
}
void SendPacketToServer(HANDLE process, BYTE* dataBuffer, int length)
{
    DWORD ImageBase = GetProcessImageBase(process);
    DWORD SendStreamData = Rebase(OUTGOINGDATASTREAM, ImageBase);
    DWORD SendStreamLength = Rebase(OUTGOINGDATALEN, ImageBase);
    DWORD SendPacketCall = Rebase(SENDOUTGOINGPACKET, ImageBase);
    SendPacketToServerEx(process, dataBuffer, length, SendStreamData, SendStreamLength, SendPacketCall);
}

/* To Client */
void WriteIncomingBuffer(HANDLE process, DWORD recvStream, BYTE* data, int length, int position)
{
    DWORD DataPointer;
    WriteProcessMemory(process, (LPVOID)(recvStream + 4), &length, 4, NULL);
    WriteProcessMemory(process, (LPVOID)(recvStream + 8), &position, 4, NULL);

    ReadProcessMemory(process, (LPVOID)recvStream, &DataPointer, 4, NULL);
    WriteProcessMemory(process, (LPVOID)DataPointer, data, length, NULL);
}
LPVOID CreateRemoteBuffer(HANDLE process, BYTE* dataBuffer, int length)
{
    LPVOID RemoteBufferPointer = VirtualAllocEx(process, NULL, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(process, RemoteBufferPointer, dataBuffer, length, NULL);
    return RemoteBufferPointer;
}

void SendPacketToClientEx(HANDLE process, BYTE* dataBuffer, int length, DWORD RecvStream, DWORD ParserCall)
{
    DWORD MainThreadId = GetProcessMainThreadId(process);
    HANDLE MainThread = OpenAndSuspendThread(MainThreadId);

    DWORD DataPointer;
    int OldLength, OldPosition;
    BYTE OldDataBuffer[4096];
    ReadProcessMemory(process, (LPVOID)(RecvStream + 4), &OldLength, 4, NULL);
    ReadProcessMemory(process, (LPVOID)(RecvStream + 8), &OldPosition, 4, NULL);
    ReadProcessMemory(process, (LPVOID)RecvStream, &DataPointer, 4, NULL);
    ReadProcessMemory(process, (LPVOID)DataPointer, OldDataBuffer, OldLength, NULL);

    WriteIncomingBuffer(process, RecvStream, dataBuffer, length, 0);

    BYTE CodeCave[10] = { 0xB8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xC3 }; //MOV EAX, <DWORD> | CALL EAX | RETN
    memcpy(&CodeCave[1], &ParserCall, 4);
    LPVOID CodeCavePointer = CreateRemoteBuffer(process, CodeCave, 10);

    ExecuteRemoteCode(process, CodeCavePointer, (LPVOID)0);

    VirtualFreeEx(process, CodeCavePointer, 10, MEM_RELEASE);
    WriteIncomingBuffer(process, RecvStream, OldDataBuffer, OldLength, OldPosition);

    ResumeAndCloseThread(MainThread);
}
void SendPacketToClient(HANDLE process, BYTE* dataBuffer, int length)
{
    DWORD ImageBase = GetProcessImageBase(process);
    DWORD RecvStream = Rebase(INCOMINGDATASTREAM, ImageBase);
    DWORD ParserCall = Rebase(PARSERFUNC, ImageBase);
    SendPacketToClientEx(process, dataBuffer, length, RecvStream, ParserCall);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    return TRUE;
}
0
BYTE* CreateOutgoingBuffer(BYTE* actualBuffer, BYTE* dataBuffer, int length) // powinna się nazywać PrepareOutgoingBuffer
{
    ZeroMemory((LPVOID)actualBuffer, 8);
    memcpy((LPVOID)&actualBuffer[8], (LPVOID)dataBuffer, length);
    return actualBuffer;
}

...

//length += 8; <--- USUNĄĆ
BYTE actualBuffer[1024];

CreateOutgoingBuffer(actualBuffer, dataBuffer, length);
...

WriteProcessMemory(process, (LPVOID)SendStreamData, actualBuffer, length, NULL);

Dobra, tu masz poprawioną wersję, bo widzę, że nie kumasz tematu w ogóle.

0

teraz to wywala na "HANDLE WorkThread = CreateRemoteThread(process, NULL, NULL, (LPTHREAD_START_ROUTINE)codeAddress, arg, NULL, NULL);" w funkcji ExecuteRemoteCode

0

ExecuteRemoteCode wywoływana jest w dwóch funkcjach: SendPacketToClientEx i SendPacketToServerEx. Która generuje błąd?

0

No nadal stoi w "WaitForSingleObject(WorkThread, INFINITE);" w obu : ToServer i ToClient.

0

Błędów w kodzie nie widzę, ale określ jawnie konwencję wywołania funkcji eksportowanych przez DLL-kę.

1 użytkowników online, w tym zalogowanych: 0, gości: 1