Hooking detours Recv and Send fuctions Empty Data

11/14/2017 19:25 leandro5#1
Hello guys acctually i Hooked the Send and Recv fuctions but kinda just 2 or 3 packets works fine like login , charserver when try to go MapServer it's crash analysing the packet it's are empty kinda how the Buffer is writed in another previous packet or something else. the game packets dont have encryption. will share my code here to see what can be doing wrong.


Code:
 #include <cstdio>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <string>
#include <windows.h>
#include "detours.h"
//#include "WinSock2.h"


// DBO int __stdcall recv(SOCKET s, char *buf, int len, int flags);
// DBO int __stdcall send(SOCKET s, const char *buf, int len, int flags);
#pragma comment( lib, "Ws2_32.lib" )
#pragma comment( lib, "detours.lib" )

PVOID Original_WinSock_Send_Function = (PVOID)0x579414;
PVOID Original_WinSock_Recv_Function = (PVOID)0x579418;

int (WINAPI *Original_Send)(SOCKET s, const char *buf, int len, int flags) = NULL;//send;
int (WINAPI *Original_Recv)(SOCKET s, char *buf, int len, int flags) = NULL;//recv;


int WINAPI Hooked_Send(SOCKET s, const char* buf, int len, int flags);
int WINAPI Hooked_Recv(SOCKET s, char *buf, int len, int flags);

char dp[64000] = { 0 };

char * packet_to_text(char* buf, int len)
{
    int c, c2, c3, c4;

    c = c2 = c3 = c4 = 0;
    sprintf(&dp[c2++], "\n");
    for (c = 0; c<len; c++)
    {
        if (c3 == 16)
        {
            for (; c4<c; c4++)
                if (buf[c4] >= 0x20)
                    dp[c2++] = buf[c4];
                else
                    dp[c2++] = 0x002E;
            c3 = 0;
            sprintf(&dp[c2++], "\n");
        }

        if ((c == 0) || !(c % 16))
        {
            sprintf(&dp[c2], "(%04X) ", c);
            c2 += 7;
        }

        sprintf(&dp[c2], "%02X ", buf[c]);
        c2 += 3;
        c3++;
    }

    if (len % 16)
    {
        c3 = len;
        while (c3 % 16)
        {
            sprintf(&dp[c2], "   ");
            c2 += 3;
            c3++;
        }
    }

    for (; c4<c; c4++)
        if (buf[c4] >= 0x20)
            dp[c2++] = buf[c4];
        else
            dp[c2++] = 0x2E;
    sprintf(&dp[c2++], "\n");
    dp[c2] = 0;
    return (char*)&dp[0];
}

void WriteLog(const char* fl, const char* fmt, ...)
{
    va_list args; // you using unicode or ascii? ascii
    char text[4096];
    char logbuf[4096];
    char buf[4096];

    SYSTEMTIME rawtime;

    FILE *fp;


    GetLocalTime(&rawtime);
    va_start(args, fmt);
    vsprintf(text, fmt, args);
    va_end(args);

    strcat(text, "\n");

    sprintf(&logbuf[0], "log\\%s%02u%02u%04u.log", fl, rawtime.wMonth, rawtime.wDay, rawtime.wYear);

    sprintf(&buf[0], "[%02u-%02u-%u, %02u:%02u:%02u] %s", rawtime.wMonth, rawtime.wDay, rawtime.wYear,
        rawtime.wHour, rawtime.wMinute, rawtime.wSecond, text);

    fp = fopen(&logbuf[0], "a");

    if (!fp)
    {
        return;
    }
    else
    {
        fprintf(fp, buf);
        fclose(fp);
    }
}

int WINAPI Hooked_Recv(SOCKET s, char *buf, int len, int flags)

{
    //My recv function

    char temp[40] = { 0 };
    //sprintf(&temp[0], "Buffer Pointer: 0x%04x", buf);
    //MessageBox(NULL, temp, temp, 0);
    WriteLog("packet" /* File Name will be packet_datestamp.log  in a folder called log */, packet_to_text(buf, len));
    return Original_Recv(s, buf, len, flags);
}
// now i just need to compile this into DLL ?

int WINAPI Hooked_Send(SOCKET s, const char *buf, int len, int flags) {


    //My send function
    return Original_Send(s, buf, len, flags);
}

BOOL WINAPI DllMain(HINSTANCE, DWORD dwReason, LPVOID) {
    switch (dwReason) {
    case DLL_PROCESS_ATTACH:
        AllocConsole();
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        Original_Send = (int (WINAPI *)(SOCKET s, const char *buf, int len, int flags))DetourFindFunction("wsock32.dll", "send");
        Original_Recv = (int (WINAPI *)(SOCKET s, char *buf, int len, int flags))DetourFindFunction("wsock32.dll", "recv");
        if (!Original_Send) MessageBox(NULL, "Send", "Broke", 0);
        if (!Original_Recv) MessageBox(NULL, "Recv", "Broke", 0);
        //DetourAttach(&(PVOID &)Original_WinSock_Send_Function, Hooked_WinSock_Send_Function);
        DetourAttach(&(PVOID &)Original_Send, Hooked_Send);
        //DetourAttach(&(PVOID &)Original_WinSock_Recv_Function, Hooked_WinSock_Recv_Function);
        DetourAttach(&(PVOID &)Original_Recv, Hooked_Recv);
        DetourTransactionCommit();
        break;
    case DLL_PROCESS_DETACH:
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID &)Original_Send, Hooked_Send);
        DetourDetach(&(PVOID &)Original_Recv, Hooked_Recv);
        DetourTransactionCommit();
        break;
    }
    return TRUE;
}
11/14/2017 20:32 Spirited#2
What error does it crash with? Might just be a memory violation. You can check the Windows Event Viewer if you're not catching errors or checking error codes. I can't desk check your code right this second, but hopefully that'll point you in the right direction.
11/14/2017 20:43 boDil#3
For starters, that's not how "recv" works: [Only registered and activated users can see links. Click Here To Register...]

Also your "packet_to_text" and "WriteLog" (what the fuck is up with those naming conventions, by the way?) functions are probably not correct either, although it's kind of hard to tell since the code is so fucking terrible.
11/14/2017 20:47 leandro5#4
Quote:
Originally Posted by Spirited View Post
What error does it crash with? Might just be a memory violation. You can check the Windows Event Viewer if you're not catching errors or checking error codes. I can't desk check your code right this second, but hopefully that'll point you in the right direction.
i tried to log it and also to display packet it's all zero maybe for it crashing client.

Quote:
Originally Posted by boDil View Post
For starters, that's not how "recv" works: [Only registered and activated users can see links. Click Here To Register...]

Also your "packet_to_text" and "WriteLog" (what the fuck is up with those naming conventions, by the way?) functions are probably not correct either, although it's kind of hard to tell since the code is so fucking terrible.
Well this is my first Hook so i guess you right it terrible but. Only say it terrible and not help will solve nothing to me...... i think my way of log working fine because it's logging the packets but it's just empty : 00 00 ...... 00
11/14/2017 21:01 boDil#5
Quote:
Originally Posted by leandro5 View Post
Well this is my first Hook so i guess you right it terrible but. Only say it terrible and not help will solve nothing to me...... i think my way of log working fine because it's logging the packets but it's just empty : 00 00 ...... 00
Can you read? Let me try again:
That is not how "recv" works: [Only registered and activated users can see links. Click Here To Register...]

Here's another hint:
Quote:
If no error occurs, recv returns the number of bytes received and the buffer pointed to by the buf parameter will contain this data received. If the connection has been gracefully closed, the return value is zero.
11/14/2017 22:12 leandro5#6
Quote:
Originally Posted by boDil View Post
Can you read? Let me try again:
That is not how "recv" works: [Only registered and activated users can see links. Click Here To Register...]

Here's another hint:
okay following your tips. Reading this !

you meant this part : Return value

If no error occurs, recv returns the number of bytes received and the buffer pointed to by the buf parameter will contain this data received. If the connection has been gracefully closed, the return value is zero.
Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Att.
11/14/2017 23:51 { Angelius }#7
This:
Code:
WriteLog("packet" /* File Name will be packet_datestamp.log  in a folder called log */, packet_to_text(buf, len));
    return Original_Recv(s, buf, len, flags);
Should be this:

Code:
int Size = Original_Recv(s, buf, len, flags);
//Size should be > 0 here.
packet_to_text(buf, Size);
return Size;
So basically you are not calling the detoured recv function to fill in the buffer for you first so it will always be empty because the client clears it before it calls the recv function.

And the reason you see packets during the Auth process is because the client doesn't actually clear the buffer it just overrides what there, So what you are seeing is chunks of the previous packet not the current packet being processed.

Also you are passing len to packet_to_text which is wrong because len is "The length, in bytes, of the buffer pointed to by the buf parameter."
Which is not the same as the number of bytes that were actually received by the function.

Plenty of flaws in your code but I don't have the time to cover it all, I am just going to say I appreciate the fact that you are trying.. Keep at it.

Quote:
Originally Posted by boDil View Post
Also your "packet_to_text" and "WriteLog" (what the fuck is up with those naming conventions, by the way?) functions are probably not correct either, although it's kind of hard to tell since the code is so fucking terrible.
Please stfu.
11/15/2017 08:05 boDil#8
Quote:
Originally Posted by { Angelius } View Post
This:
Code:
WriteLog("packet" /* File Name will be packet_datestamp.log  in a folder called log */, packet_to_text(buf, len));
    return Original_Recv(s, buf, len, flags);
Should be this:

Code:
int Size = Original_Recv(s, buf, len, flags);
//Size should be > 0 here.
packet_to_text(buf, Size);
return Size;
So basically you are not calling the detoured recv function to fill in the buffer for you first so it will always be empty because the client clears it before it calls the recv function.

And the reason you see packets during the Auth process is because the client doesn't actually clear the buffer it just overrides what there, So what you are seeing is chunks of the previous packet not the current packet being processed.

Also you are passing len to packet_to_text which is wrong because len is "The length, in bytes, of the buffer pointed to by the buf parameter."
Which is not the same as the number of bytes that were actually received by the function.

Plenty of flaws in your code but I don't have the time to cover it all, I am just going to say I appreciate the fact that you are trying.. Keep at it.
Good job spoon-feeding him instead of letting him figure it out for himself.

Quote:
Originally Posted by { Angelius } View Post
Please stfu.
Why? What I said might have been harsh, but it's still true. It's hard to tell if those functions actually work when the code is so bad.
11/15/2017 13:20 dedlyblady150#9
Quote:
Originally Posted by { Angelius } View Post
This:
Code:
WriteLog("packet" /* File Name will be packet_datestamp.log  in a folder called log */, packet_to_text(buf, len));
    return Original_Recv(s, buf, len, flags);
Should be this:

Code:
int Size = Original_Recv(s, buf, len, flags);
//Size should be > 0 here.
packet_to_text(buf, Size);
return Size;
So basically you are not calling the detoured recv function to fill in the buffer for you first so it will always be empty because the client clears it before it calls the recv function.

And the reason you see packets during the Auth process is because the client doesn't actually clear the buffer it just overrides what there, So what you are seeing is chunks of the previous packet not the current packet being processed.

Also you are passing len to packet_to_text which is wrong because len is "The length, in bytes, of the buffer pointed to by the buf parameter."
Which is not the same as the number of bytes that were actually received by the function.

Plenty of flaws in your code but I don't have the time to cover it all, I am just going to say I appreciate the fact that you are trying.. Keep at it.



Please stfu.
Adel i need your help if u still help pepole :)
11/15/2017 13:51 leandro5#10
Quote:
Originally Posted by { Angelius } View Post
This:
Code:
WriteLog("packet" /* File Name will be packet_datestamp.log  in a folder called log */, packet_to_text(buf, len));
    return Original_Recv(s, buf, len, flags);
Should be this:

Code:
int Size = Original_Recv(s, buf, len, flags);
//Size should be > 0 here.
packet_to_text(buf, Size);
return Size;
So basically you are not calling the detoured recv function to fill in the buffer for you first so it will always be empty because the client clears it before it calls the recv function.

And the reason you see packets during the Auth process is because the client doesn't actually clear the buffer it just overrides what there, So what you are seeing is chunks of the previous packet not the current packet being processed.

Also you are passing len to packet_to_text which is wrong because len is "The length, in bytes, of the buffer pointed to by the buf parameter."
Which is not the same as the number of bytes that were actually received by the function.

Plenty of flaws in your code but I don't have the time to cover it all, I am just going to say I appreciate the fact that you are trying.. Keep at it.



Please stfu.
Thanks your tips helped me alot !

Will keep working on this will post results here soon.

Quote:
i did so :

int iRet = Original_Recv(s, buf, len, flags);
if (iRet > 0) {
WriteLog("Recv_Packet" /* File Name will be packet_datestamp.log in a folder called log */, packet_to_text(buf, len));
}
return iRet;
Now it's loging right but weird when i go from CharServer to MapServer this kinda messing up the packets loading character incomplete in the map also happen when i teleport to other Map. Others thing kinda fine...

Quote:
Originally Posted by Spirited View Post
What error does it crash with? Might just be a memory violation. You can check the Windows Event Viewer if you're not catching errors or checking error codes. I can't desk check your code right this second, but hopefully that'll point you in the right direction.

Did what you said look :

Code:
- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="Application Error" /> 
  <EventID Qualifiers="0">1000</EventID> 
  <Level>2</Level> 
  <Task>100</Task> 
  <Keywords>0x80000000000000</Keywords> 
  <TimeCreated SystemTime="2017-11-15T15:35:59.000000000Z" /> 
  <EventRecordID>122027</EventRecordID> 
  <Channel>Application</Channel> 
  <Computer>Kelb-PC</Computer> 
  <Security /> 
  </System>
- <EventData>
  <Data>DBO-Local.exe</Data> 
  <Data>1.0.0.1</Data> 
  <Data>4d0860c9</Data> 
  <Data>unknown</Data> 
  <Data>0.0.0.0</Data> 
  <Data>00000000</Data> 
  <Data>c0000005</Data> 
  <Data>2e2e2e2e</Data> 
  <Data>df0</Data> 
  <Data>01d35e27300efbab</Data> 
  <Data>D:\Games\DBO-Local.exe</Data> 
  <Data>unknown</Data> 
  <Data>ad5927d9-ca1a-11e7-a0e2-00ace74c50a6</Data> 
  </EventData>
  </Event>
For true this Error happens when i try to use WEP to log packets while DLL is inject! so client crash ! if i just inject DLL and try to loginmap this return wrong packet but i cant really confirm it because i cant log with WEP or client crash.

Comparing the packet's its looks more a acess violation of memory.... now need to figure out.

Here where game stopps access violation

[Only registered and activated users can see links. Click Here To Register...]

Hello guys i found what was causing the acess violation it's because log fuction maybe taking much time to be executed soit overcome wait time of Client. Any tips to this problem !? because my intention is use it for a packet bot.... so maybe my fuctions also will take some time to be executed i cant work with so less time..
11/16/2017 23:07 Xio.#11
Quote:
Originally Posted by leandro5 View Post
i cant work with so less time..
Yes you can. Copy the packet to a queue/array and return.
11/17/2017 00:18 leandro5#12
Quote:
Originally Posted by Xio. View Post
Yes you can. Copy the packet to a queue/array and return.
Trying to do this but get worse Lol:

Code:
HANDLE hThreads;

typedef struct st_savebuffer {
 char * buf;
 int len;
} SAVEBUFFER;


 SAVEBUFFER SaveBuffer = { buf, len };
 //hThreads = (HANDLE)_beginthread(savebuffer, 0, (void*)&SaveBuffer);
 hThreads = (HANDLE)_beginthread((void(*)(void*))savebuffer, 0, (void*)&SaveBuffer);