[C++] Stuck on calling a function from samp.dll

proteh

Member
Joined
Jun 18, 2013
Messages
21
Reaction score
0
Hello. I'm making a tool for SAMP and now I needed to make a function to write something to the chat.

This is what I have so far, but it won't work and I don't know what's wrong. I dont fully understand how to call the function and pass the message to write to it.

Code:
[...]

struct DataToSend {

    int address;
    int data;
};

bool addChatMessage(HANDLE *gtaProc, DWORD *sampBaseAddress, char *msg) {

    if(*gtaProc == NULL || *sampBaseAddress == 0x0 || sampBaseAddress == NULL)
        return false;

    DWORD sampChatInfoAddress;
    DWORD msgMemory;

    int result = ReadProcessMemory(*gtaProc, (LPVOID)(*sampBaseAddress + ADDR_SAMP_CHATMSG_PTR), &sampChatInfoAddress, sizeof(sampChatInfoAddress), NULL);

    if(!result || sampChatInfoAddress == 0x0)
        return false;

    msgMemory = (DWORD)VirtualAllocEx(*gtaProc, 0, 4096, 0x1000 | 0x2000, 0x40);
    WriteProcessMemory(*gtaProc, (LPVOID)msgMemory, msg, 256, NULL);
    DataToSend mydata = { (int)sampChatInfoAddress, (int)msgMemory };
    WriteProcessMemory(*gtaProc, (LPVOID)(*sampBaseAddress + ADDR_SAMP_FUNC_ADDCHATMSG), (LPVOID)&mydata, sizeof(mydata), NULL);
    return true;
}
[...]

When I call the function nothing won't appear in the chat box.

Thanks.
 

T3KTONIT

Well-known member
Joined
Sep 2, 2013
Messages
308
Reaction score
5
bool addChatMessage(HANDLE *gtaProc, DWORD *sampBaseAddress, char *msg) {

    if(*gtaProc == NULL || *sampBaseAddress == 0x0 || sampBaseAddress == NULL)
        return false;

    DWORD sampChatInfoAddress;
    DWORD msgMemory;

    int result = ReadProcessMemory(*gtaProc, (LPVOID)(*sampBaseAddress + ADDR_SAMP_CHATMSG_PTR), &sampChatInfoAddress, sizeof(sampChatInfoAddress), NULL);

    if(!result || sampChatInfoAddress == 0x0)
        return false;

    msgMemory = (DWORD)VirtualAllocEx(*gtaProc, 0, 4096, 0x1000 | 0x2000, 0x40);
    WriteProcessMemory(*gtaProc, (LPVOID)msgMemory, msg, 256, NULL);
    DataToSend mydata = { (int)sampChatInfoAddress, (int)msgMemory };
    WriteProcessMemory(*gtaProc, (LPVOID)(*sampBaseAddress + ADDR_SAMP_FUNC_ADDCHATMSG), (LPVOID)&mydata, sizeof(mydata), NULL);
    return true;



You're writing memory, you're modifying memory not calling a function from the samp module, if you want to call a function, you need to know the function's address, the function's arguments(parameters), the datatype of parameters, and the function's calling convention. (__stdcall, __cdecl, __fastcall, etc...)

also, if u want to call it, you have to either use the inline assembler, (__asm push arg , __asm call eax),
or you can typedef it(typedef int (__thiscall *___GetPlayerOSStructureOI)(DWORD bpStatPointer);), which is a more advanced way, i suggest u use the inline assembler way, cuz its easier.

So. please get your datas straight before u axe some dum qwestion again. thx bye.
 

proteh

Member
Joined
Jun 18, 2013
Messages
21
Reaction score
0
Alright. So now I have this:

Code:
bool addChatMessage(HANDLE *gtaProc, DWORD *sampBaseAddress, char *msg) {

    if(*gtaProc == NULL || *sampBaseAddress == DIR_NULA || sampBaseAddress == NULL)
        return 0;

    int chatinfo = (int)*sampBaseAddress + FUNC_SAMP_ADDCHATMSG;
    int func = (int)*direccionBase + ADDR_SAMP_CHAT_INFO;

    __asm mov eax, dword ptr[chatinfo]
    __asm mov ecx, dword ptr[eax]
    __asm push 0
    __asm push 0xFFFFFF // Msg color
    __asm push 0
    __asm push msg
    __asm push 8
    __asm call func
    return true;
}

But I get a "access violation" on line "__asm mov ecx, dword ptr[eax]" when I try to call the function, and I don't know what's wrong now.
 

0x_

Wtf I'm not new....
Administrator
Joined
Feb 18, 2013
Messages
1,119
Reaction score
168
[member=2896]proteh[/member]
WTF are you trying? for inline assembly you need to be inside the process.
you're doing pardon me, bullshit right now.
 

bartekdvd

Member
Joined
Jan 24, 2014
Messages
20
Reaction score
4
You don't exactly need to be in target process to call the function. You can do this via remote process by injecting asm code - VirtualAllocEx, WriteProcessMemory and setting up some hooks. The other way is by calling SetThreadContext and changing EIP of main thread (for example) to start address of your function (and do a lot more stuff to not crash the game). Also if a function takes zero or only one argument you can just use CreateRemoteThread on that function - not recommended, cause samp is not thread safe (except RakNet) and it may crash. You can combine CreateRemoteThread with injecting your own code that does some magic to not crash the game.

All of this is rather advanced stuff, so I would just inject a DLL and call the function from there.
 

T3KTONIT

Well-known member
Joined
Sep 2, 2013
Messages
308
Reaction score
5
Noob Retard link said:
You don't exactly need to be in target process to call the function. You can do this via remote process by injecting asm code - VirtualAllocEx, WriteProcessMemory and setting up some hooks. The other way is by calling SetThreadContext and changing EIP of main thread (for example) to start address of your function (and do a lot more stuff to not crash the game). Also if a function takes zero or only one argument you can just use CreateRemoteThread on that function - not recommended, cause samp is not thread safe (except RakNet) and it may crash. You can combine CreateRemoteThread with injecting your own code that does some magic to not crash the game.

All of this is rather advanced stuff, so I would just inject a DLL and call the function from there.

Yeah, i agree but, doing it remotely is a rather long process... takes a few more lines of code.
 
Top