procedure EntryPoint(Reason: DWORD);
begin
If Reason = DLL_PROCESS_ATTACH Then
begin
HookCode(Pointer(AddressZChatInput),@ZChatInputCallBack,@ZChatInputNextHook);
end;
end;
type
TZChatOutput = procedure(Buffer: PChar; iType: Integer; iLoc: Integer; ChatColor: TColor); cdecl;
TZChatInputNextHook = Function (Text: PChar): Boolean; cdecl;
var
ZChatOutput : TZChatOutput = TZChatOutput(AddressZChatOutput);
ZChatInputNextHook : TZChatInputNextHook;
procedure Echo(Output: String);
function ZChatInputCallBack(Text: PChar): Boolean; cdecl;
implementation
function ZChatInputCallBack(Text: PChar): Boolean; cdecl;
begin
Echo('test');
Result := ZChatInputNextHook(Text);
//If I have the result line commented out I get buffer overrun.
//If it's not commented, SUB EAX,DWORD PTR DS:[ESI+20] in the callback
// returns an error and crashes the main app. ESI is 00000000 for some reason...
end;
procedure Echo(Output: String);
var
Buffer : PChar;
begin
If Length(Output) < 127 Then
begin
If @ZChatOutput <> nil Then
begin
GetMem(buffer, 128);
try
StrPCopy(Buffer,Output);
ZChatOutput(Buffer,cmtSystem,clCurrent,$FFFFFFFF);
finally
FreeMem(buffer);
end;
end;
end;
end;
function ZChatInputCallBack(Text: PChar): Boolean; stdcall;
var
Output : String;
begin
try
Output := '[ThievingSix] ' + Text;
If Length(Output) > 127 Then
Exit;
Realloc(Text, length(output)+1);
StrPCopy(text,Output);// make sure this overwrites text with output no matter what's in text, otherwise make text[0]:=#0 before the call. I haven't used pchar functions in ages
finally
Result := ZChatInputNextHook(Text);
end;
end;
function ZChatInputCallBack(Text: PChar): Boolean; stdcall;
var
Output : String;
F : TextFile;
begin
AssignFile(F,'C:\ircgunz.log');
ReWrite(F);
Try
Writeln(F,'Start');
Output := '[ThievingSix] ' + Text;
WriteLn(F,Output);
If Length(Output) > 127 Then Exit;
Writeln(F,'Length OK');
Writeln(F,IntToStr(Integer(@Text)));
ReallocMem(Text,Length(Output) + 1);
Writeln(F,'Realloc');
Writeln(f,Text);
StrPCopy(Text,Output);
Writeln(F,'copy');
Writeln(f,Text);
Finally
Writeln(f,'Finally');
Writeln(F,Text);
Writeln(F,IntToStr(Integer(@Text)));
CloseFile(F);
Result := ZChatInputNextHook(Text);
end;
end;
DWORD ZChat__Input = ADDR_ZCHATINPUT;
CDetour ZChat__InputDet;
bool __stdcall ZChat__InputHook(const char* lpcLine){
bool bRet = true;
//Info
if(stricmp(lpcLine, "!info") == 0){
bRet = false;
Echo("GunzHax " VERSION " Running - Written by stosw / LanceVorgin");
//Unload
}else if(stricmp(lpcLine, "!unload") == 0){
bRet = false;
Echo("GunzHax Unloading");
//Here's some magic - get the original return address of the ZChat__Input caller and slap that mofo in g_dwUnloadRetAddr
g_dwUnloadRetAddr = (DWORD)ZChat__InputDet.GetGateRetAddress();
//Set the address our hook returns to to our UnloadProc
ZChat__InputDet.SetGateRetAddress((BYTE*)UnloadProc);
//Respawn
}else if(stricmp(lpcLine, "!spawn") == 0){
bRet=false;
Repsawn();
//Kill
}else if(memcmp((void*)lpcLine, "!kill ", 6) == 0){
bRet=false;
sscanf(lpcLine, "!kill %d", &uidInput);
uidChar->secondID=uidInput;
ZPostGameKill(uidChar);
//Are the first 7 characters "!fkmsg " ?
}else if(memcmp((void*)lpcLine, "!fkmsg ", 7) == 0)
//If so, replace that shit with new lines, but let the modified message be sent to the real chat handler
memset((void*)lpcLine, '\n', 7);
//Only return back to the original function (e.g. only let Gunz send the chat string) if bRet is true
ZChat__InputDet.Ret(bRet);
//Return true, telling Gunz that the string was handled (returning false will make whatever was typed stay in the box)
return true;
}
typedef void (__cdecl* ZChatOutputFunc)(const char* lpcMsg, int iType /*= 0*/,int iLoc /*= 0*/, DWORD dwColor);
ZChatOutputFunc ZChatOutput = (ZChatOutputFunc)ADDR_ZCHATOUTPUT;
void Echo(const char* lpcFmt, ...){
char szBuf[0x4000];
va_list vaArgs;
va_start(vaArgs, lpcFmt);
_vsnprintf(szBuf, sizeof(szBuf), lpcFmt, vaArgs);
va_end(vaArgs);
ZChatOutput(szBuf, 2, 0, 0xFFFFFFFF);
}
you've got some demos there as well. the componets are pretty easy to use and from my experience they work just fine.
I know you are using some other means of injecting but ... maybe you'll get to like madhis's components :P
(I didn't forget about the other quesiton. tab open. I just don't have anything to say yet)