- 4,803
- 6,475
- Версия SA-MP
-
- 0.3.7 (R1)
- 0.3.7-R3
Делает ID в никах белыми, и состоящими всегда из 3х цифр:
@Tema05 возможно с D или CLEO тебе будет перевести легче, чем с плюсов
no-fill-id - версия без заполнения id нулями
версию на lua использовать не рекомендуется, там пиздец в хуке, она написана только ради чела, который несколько дней ноет на форуме с этими никами
D:
module WhiteNicksIds;
import core.sys.windows.windows;
import core.sys.windows.dll;
import core.runtime;
import std.concurrency : spawn, yield;
import core.stdc.string : memcpy;
import core.stdc.stdio : snprintf;
extern (Windows) BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID) {
final switch (ulReason) {
case DLL_PROCESS_ATTACH:
Runtime.initialize();
spawn({
while (*cast(uint*)0xC8D4C0 < 9)
yield();
samp = cast(DWORD)GetModuleHandleA("samp");
isR1 = *cast(ubyte *)( samp + 0x129 ) == 0xF4;
hook_addr = cast(void*)(samp + (isR1 ? HOOK_ADDR_R1 : HOOK_ADDR_R3));
InstallHook();
});
dll_process_attach(hInstance, true);
break;
case DLL_PROCESS_DETACH:
RemoveHook();
Runtime.terminate();
dll_process_detach(hInstance, true);
break;
case DLL_THREAD_ATTACH:
dll_thread_attach(true, true);
break;
case DLL_THREAD_DETACH:
dll_thread_detach(true, true);
break;
}
return true;
}
void InstallHook(){
auto relative_addr = cast(DWORD)&name_hook - (cast(DWORD)hook_addr + HOOK_LEN);
DWORD vp;
hook_addr.VirtualProtect(HOOK_LEN, PAGE_EXECUTE_READWRITE, &vp);
*cast(DWORD*)(hook_addr + 1) = relative_addr;
hook_addr.VirtualProtect(HOOK_LEN, vp, &vp);
}
void RemoveHook(){
auto hook_code = cast(char*)(isR1 ? HOOK_CODE_R1 : HOOK_CODE_R3);
DWORD vp;
hook_addr.VirtualProtect(HOOK_LEN, PAGE_EXECUTE_READWRITE, &vp);
hook_addr.memcpy(hook_code, HOOK_LEN);
hook_addr.VirtualProtect(HOOK_LEN, vp, &vp);
}
private {
extern (C) auto name_hook( char* buf, const(char*) fmt, const(char*) nick, const(DWORD) ID ) @nogc{
return buf.snprintf(128, "%s {FFFFFF}(%03d)", nick, ID);
}
const HOOK_ADDR_R1 = 0x70F4E;
const HOOK_ADDR_R3 = 0x74E3F;
const HOOK_LEN = 5;
const HOOK_CODE_R1 = "\xE8\xA0\x4C\x04\x00";
const HOOK_CODE_R3 = "\xE8\x4F\x2D\x05\x00";
__gshared DWORD samp;
__gshared bool isR1;
__gshared void* hook_addr;
}
CLEO:
{$CLEO}
wait 2000
0AA2: 1@ = load_library "samp.dll"
0A8E: 2@ = 1@ + 0x129
0A8D: 2@ = read_memory 2@ size 1 virtual_protect 1
if 2@ == 0xF4 // isR1
then
0A8E: 2@ = 1@ + 0x70F4E // R1
else
0A8E: 2@ = 1@ + 0x74E3F // R3
end
// Prepare asm
0AC6: 0@ = label @asm_hook offset
0AC7: 3@ = 0@ offset // ptr to var with buffer
0AC7: 4@ = 1@ offset // ptr to var with format
0AC7: 5@ = 2@ offset // ptr to var with nick
0AC7: 6@ = 3@ offset // ptr to var with id
000A: 0@ += 5 // mov [0@], eax
0A8C: write_memory 0@ size 4 value 3@ virtual_protect 1
000A: 0@ += 9 // mov [1@], eax
0A8C: write_memory 0@ size 4 value 4@ virtual_protect 1
000A: 0@ += 9 // mov [2@], eax
0A8C: write_memory 0@ size 4 value 5@ virtual_protect 1
000A: 0@ += 9 // mov [3@], eax
0A8C: write_memory 0@ size 4 value 6@ virtual_protect 1
0AC6: 3@ = label @asm_hook offset
000A: 0@ += 5 // mov eax, IP
0AC6: 5@ = label @name_hook offset
0A8C: write_memory 0@ size 4 value 5@ virtual_protect 1
0A9F: 1@ = current_thread_pointer
0A8E: 4@ = 1@ + 0x14 // ptr to IP of this thread
000A: 0@ += 5 // mov [IP], eax
0A8C: write_memory 0@ size 4 value 4@ virtual_protect 1
000A: 0@ += 6 // mov eax, [IP]
0A8C: write_memory 0@ size 4 value 4@ virtual_protect 1
000A: 0@ += 5 // cmp eax, @name_hook
0A8C: write_memory 0@ size 4 value 5@ virtual_protect 1
000A: 0@ += 7 // mov ecx, thread
0A8C: write_memory 0@ size 4 value 1@ virtual_protect 1
000A: 0@ += 4 // call CRunningScript::ProcessOneCommand
0AB1: @asm_call_hook 2 address 0@ callback 0x00469EB0
// fix CLEO opcodes for CRunningScript::ProcessOneCommand
0A8D: 1@ = read_memory 0x00469FEE size 4 virtual_protect 1
0A8C: write_memory 0x00469EF0 size 4 value 1@ virtual_protect 1
// InstalHook
0AC6: 0@ = label @asm_hook offset
0AB1: @asm_call_hook 2 address 2@ callback 0@
// RemoveHook
0AB1: @installDtor 1 callback @on_unload_script
:mainloop
while true
wait 0
end
:on_unload_script
0AA2: 10@ = load_library "samp.dll"
0A8E: 20@ = 10@ + 0x129
0A8D: 20@ = read_memory 20@ size 1 virtual_protect 1
if 20@ == 0xF4 // isR1
then
0A8E: 10@ = 10@ + 0x70F4E // R1
else
0A8E: 10@ = 10@ + 0x74E3F // R3
end
0A8C: write_memory 10@ size 1 value 0xE8 virtual_protect 1
10@ += 1
if 20@ == 0xF4 // isR1
then
0A8C: write_memory 10@ size 1 value 0xA0 virtual_protect 1
10@ += 1
0A8C: write_memory 10@ size 1 value 0x4C virtual_protect 1
10@ += 1
0A8C: write_memory 10@ size 1 value 0x04 virtual_protect 1
else
0A8C: write_memory 10@ size 1 value 0x4F virtual_protect 1
10@ += 1
0A8C: write_memory 10@ size 1 value 0x2D virtual_protect 1
10@ += 1
0A8C: write_memory 10@ size 1 value 0x05 virtual_protect 1
end
10@ += 1
0A8C: write_memory 10@ size 1 value 0x00 virtual_protect 1
0A93: end_custom_thread
:name_hook // 0@ - buf, 1@ - fmt, 2@ - nick, 3@ - ID
0AD3: 0@ = format "%s {FFFFFF}(%03d)" 2@ 3@
jump @mainloop
:asm_hook
hex
// copy args to script variables
8b 44 24 04 // mov eax, [esp+0x4]
a3 00000000 // mov [0@], eax
8b 44 24 08 // mov eax, [esp+0x8]
a3 00000000 // mov [1@], eax
8b 44 24 0C // mov eax, [esp+0xC]
a3 00000000 // mov [2@], eax
8b 44 24 10 // mov eax, [esp+0x10]
a3 00000000 // mov [3@], eax
// change script IP to @name_hook
b8 00000000 // mov eax, IP
a3 00000000 // mov [IP], eax
51 // push ecx
// NEXT_OP:
a1 00000000 // mov eax, [IP]
3d 00000000 // cmp eax, @name_hook
7c 0c // jl SKIP
// execute opcode
b9 00000000 // mov ecx, thread
e8 00000000 // call CRunningScript::ProcessOneCommand
eb e8 // jmp NEXT_OP
// SKIP:
59 // pop ecx
c3 // ret
end
///////////////////////////////////////////////////// destructor hook /////////////////////////////////////////////////////
:installDtor // 0@ - dtor label
// fix CLEO opcodes for CRunningScript::ProcessOneCommand
0A8D: 1@ = read_memory 0x00469FEE size 4 virtual_protect 1
0A8C: write_memory 0x00469EF0 size 4 value 1@ virtual_protect 1
// initialize ptrs for prepare asm hook
0AC6: 1@ = label @asm_CRunningScript_RemoveScriptFromList_hook offset
0A9F: 2@ = current_thread_pointer
0A8E: 3@ = 2@ + 0x10 // ptr to BaseIP of this thread
0A8D: 3@ = read_memory 3@ size 4 virtual_protect 1
0A8F: 0@ = 3@ - 0@
0A8E: 3@ = 2@ + 0x14 // ptr to IP of this thread
// 0@ -- IP for @dtor
// 1@ -- asm code
// 2@ -- thread
// 3@ -- ptr to IP
// prepare asm hook
1@ += 2 // mov eax, [IP]
0A8C: write_memory 1@ size 4 value 3@ virtual_protect 1
1@ += 7 // cmp ecx, thread
0A8C: write_memory 1@ size 4 value 2@ virtual_protect 1
1@ += 7 // mov eax, @dtor
0A8C: write_memory 1@ size 4 value 0@ virtual_protect 1
1@ += 5 // mov [IP], eax
0A8C: write_memory 1@ size 4 value 3@ virtual_protect 1
1@ += 6 // call CRunningScript::ProcessOneCommand
0AB1: @asm_call_hook 2 address 1@ callback 0x00469EB0
1@ += 8 // mov eax [IP]
0A8C: write_memory 1@ size 4 value 3@ virtual_protect 1
1@ += 15 // mov [IP], eax
0A8C: write_memory 1@ size 4 value 3@ virtual_protect 1
// copy original code
0A8D: 4@ = read_memory 0x00464BD0 size 1 virtual_protect 1
1@ += 5 // install first byte of original code
0A8C: write_memory 1@ size 1 value 4@ virtual_protect 1
0A8D: 5@ = read_memory 0x00464BD1 size 4 virtual_protect 1
if or
4@ == 0xe8 // call
4@ == 0xe9 // jmp
then // fix addr of another hook
5@ += 0x00464BD5 // dest addr
0062: 5@ - 1@
5@ -= 5 // relative addr for hook
end
1@ += 1 // install remain bytes of original code
0A8C: write_memory 1@ size 4 value 5@ virtual_protect 1
// install hook to CRunningScript::RemoveScriptFromList
1@ += 4
0AB1: @asm_jmp_hook 2 address 1@ callback 0x00464BD5
0AC6: 1@ = label @asm_CRunningScript_RemoveScriptFromList_hook offset
0AB1: @asm_jmp_hook 2 address 0x00464BD0 callback 1@
0AB2: ret 0
:asm_CRunningScript_RemoveScriptFromList_hook
hex
// Save original IP
50 // push eax
a1 00000000 // mov eax, [IP]
50 // push eax
// Compare thread
81 f9 00000000 // cmp ecx, thread
75 21 // jnz SKIP
// Set dtor IP
b8 00000000 // mov eax, @dtor
a3 00000000 // mov [IP], eax
// NEXT_OP:
51 // push ecx
52 // push edx
e8 00000000 // call CRunningScript::ProcessOneCommand
5a // pop edx
59 // pop ecx
a1 00000000 // mov eax [IP]
66 8b 00 // mov ax, [eax]
66 3d 93 0a // cmp ax, 0x0A93
75 e9 // jnz NEXT_OP
// SKIP:
// Restore original IP
58 // pop eax
a3 00000000 // mov [IP], eax
58 // pop eax
0000000000 // original code
// Exit from hook
e9 00000000 // jmp 464BD5
end
/////////////////////////////////////////////////// end destructor hook ///////////////////////////////////////////////////
//////////////////////////////////////////// MogAika snippet for install hook /////////////////////////////////////////////
:asm_call_hook
0A8C: write_memory 0@ size 1 value 0xE8 virtual_protect 1
0085:3@ = 1@
0062: 1@ -= 0@ // (int)
000E: 1@ -= 5
0@ += 1
0A8C: write_memory 0@ size 4 value 1@ virtual_protect 1
0AB2: ret 0
:asm_jmp_hook
0A8C: write_memory 0@ size 1 value 0xE9 virtual_protect 1
0085:3@ = 1@
0062: 1@ -= 0@ // (int)
000E: 1@ -= 5
0@ += 1
0A8C: write_memory 0@ size 4 value 1@ virtual_protect 1
0AB2: ret 0
////////////////////////////////////////// end MogAika snippet for install hook ///////////////////////////////////////////
no-fill-id - версия без заполнения id нулями
версию на lua использовать не рекомендуется, там пиздец в хуке, она написана только ради чела, который несколько дней ноет на форуме с этими никами
Вложения
Последнее редактирование: