|
lua, readmem, unicode, Считать из памяти строку в формате UTF-16 |
|
|
фонарик |
19.2.2024, 14:37
|
Apprentice
Сообщений: 157
Регистрация: 23.11.2011 Группа: Пользователи Наличность: 13
Пользователь №: 14.305
|
Здравствуйте. Не знаю правильно ли я думаю, но пилот не умеет понимать строку в юникоде. Из интернетов были добыты эльфийские инструменты плагины, которые (если судить по светящимся надписям на них) как раз созданы магами-чародеями программистами для таких задач. Но тут вспоминается басня Крылова "Мартышка и очки". На рабочем столе уже не осталось места для размещения очередного артефакта. И вот в печалях, в довлеющем ощущении тяжести и бренности бытия, спешу я снова к вам в лавку алхимиков на форум за советами и помощью. Вот, например, у одного человека, создаваемый велосипед заканчивается чтением памяти: Код Name = readmem ("0x07CCFFD8", "S", 16) В Name записывется какое-то нечто, вообще не связанное с реальностью. По данному адресу находится: Код 1D 04 30 04 31 04 3E 04 40 04 что в переводе с древнего наречья с UTF-16 читается как слово "Набор". То ли я где-то прочёл, то ли кто-то сказал, но я почему-то знаю что необходимо обзавестись синей изолентой плагином, который нужно правильно причесать, положить в правильное место и создать заклинание на ассемблере правильную функцию, которая и считает из памяти всё в правильном виде. Но без вашей помощи мне не справится, я вообще даже не понимаю, правильно ли я в Воронеж ехал сделал ли я хоть что-то правильное в своих попытках. Пожалуйста, поделитесь советом, как же всё-таки данные из памяти правильно приготовить? Легенды гласят, доподлинно известно, что это строка в кодировке UTF-16.
|
|
|
|
DarkMaster |
19.2.2024, 16:01
|
Модератор UOPilot
Сообщений: 9.573
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 28548
Пользователь №: 11.279
|
Код --lua log"clear"
local ffi = require("ffi") local C = ffi.C local user = ffi.load('User32')
--bind WINAPI ffi.cdef [[ typedef int BOOL; typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; typedef void * LPVOID; typedef const void * LPCVOID; typedef DWORD * LPDWORD; typedef void * PVOID; typedef PVOID HANDLE; typedef HANDLE HWND; typedef long LONG_PTR; typedef LONG_PTR SIZE_T;
void *malloc(size_t size); void free(void *ptr);
DWORD GetWindowThreadProcessId(DWORD hWnd, LPDWORD lpdwProcessId); DWORD OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId); BOOL CloseHandle(DWORD hObject);
int __stdcall MultiByteToWideChar(int cp, int flag, const char* src, int srclen, wchar_t* dst, int dstlen); int __stdcall WideCharToMultiByte(int cp, int flag, wchar_t *src, int srclen, char* dst, int dstlen, const char* defchar, int* used); int __stdcall WriteProcessMemory( void *hProcess,void *lpBaseAddress,void *lpBuffer,size_t nSize,size_t *lpNumberOfBytesWritten);
BOOL ReadProcessMemory( DWORD hProcess, DWORD lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead ); ]]
local PROCESS_VM_READ = 0x0010
local export = {} export.set_buffer_size = function(size) export.buffer_raw = nil collectgarbage() export.buffer_raw = ffi.gc(C.malloc(size), C.free) export.buffer_size = size end export.set_buffer_size(128)
local ReadMemory = function (address, size) end do local PID = ffi.new('DWORD[1]') ReadMemory = function (address, size) if size > export.buffer_size then export.set_buffer_size(size) end
user.GetWindowThreadProcessId(workwindow(), PID) local process = C.OpenProcess(PROCESS_VM_READ,true, PID[0]);
if process > 0 then local result = C.ReadProcessMemory(-1, address, export.buffer_raw, size, nil) C.CloseHandle(process) if result ~= 0 then return true end end log('Process not opened') return nil, -2 end end
export.char = function (address, lenght) if ReadMemory(address, lenght) then export.buffer = ffi.cast("char *", export.buffer_raw) return export.buffer[0] end return nil end
export.byte = function (address, lenght) if ReadMemory(address, lenght) then export.buffer = ffi.cast("BYTE *", export.buffer_raw) return export.buffer[0] end return nil end
export.short = function (address, lenght) if ReadMemory(address, lenght*2) then export.buffer = ffi.cast("short *", export.buffer_raw) return export.buffer[0] end return nil end
export.word = function (address, lenght) if ReadMemory(address, lenght*2) then export.buffer = ffi.cast("WORD *", export.buffer_raw) return export.buffer[0] end return nil end
export.int = function (address, lenght) if ReadMemory(address, lenght*4) then export.buffer = ffi.cast("int *", export.buffer_raw) return export.buffer[0] end return nil end
export.dword = function (address, lenght) if ReadMemory(address, lenght*4) then export.buffer = ffi.cast("DWORD *", export.buffer_raw) return export.buffer[0] end return nil end
export.float = function (address, lenght) if ReadMemory(address, lenght*4) then export.buffer = ffi.cast("float *", export.buffer_raw) return export.buffer[0] end return nil end
export.double = function (address, lenght) if ReadMemory(address, lenght*8) then export.buffer = ffi.cast("double *", export.buffer_raw) return export.buffer[0] end return nil end
export.string = function (address, lenght) if ReadMemory(address, lenght) then export.buffer = ffi.cast("char *", export.buffer_raw) return ffi.string(export.buffer, lenght) end return nil end
--unicode to ansistring function w2astring (wString)
end
export.unicode = function (address, lenght) if export.string(address, lenght) then local wString = ffi.cast("short *", export.buffer_raw) local len = ffi.C.WideCharToMultiByte(0, 0, wString, -1, nil, 0, nil, nil) local aString = ffi.new("char[?]",len) ffi.C.WideCharToMultiByte(0, 0, wString, -1, aString, lenght, nil, nil) return ffi.string(aString) end return nil end
Оно прям из под руки. Может быть сыро, косо. Тебя интересует функция export.unicode(address, lenght), где адрес - это адрес(кто бы догадался?), lenght - длина в символах для чтения. Не в байтах! В буквах! Сообщение отредактировал DarkMaster - 19.2.2024, 16:02
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
фонарик |
19.2.2024, 16:22
|
Apprentice
Сообщений: 157
Регистрация: 23.11.2011 Группа: Пользователи Наличность: 13
Пользователь №: 14.305
|
Цитата(DarkMaster @ 19.2.2024, 16:01) Тебя интересует функция export.unicode(address, lenght) А как правильно передавать значения? Код str = export.unicode(0x07CCFFD8, 6) и далее в ковычках и без, с 0x и без - возвращает nil (IMG: style_emoticons/default/sad.gif) Как оказалось все сложно, я понимаю теперь почему длинные слова так расстраивали Винни Пуха (IMG: style_emoticons/default/unsure.gif)
|
|
|
|
DarkMaster |
19.2.2024, 16:36
|
Модератор UOPilot
Сообщений: 9.573
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 28548
Пользователь №: 11.279
|
Код --lua log"clear"
local ffi = require("ffi") local C = ffi.C local user = ffi.load('User32')
--bind WINAPI ffi.cdef [[ typedef int BOOL; typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; typedef void * LPVOID; typedef const void * LPCVOID; typedef DWORD * LPDWORD; typedef void * PVOID; typedef PVOID HANDLE; typedef HANDLE HWND; typedef long LONG_PTR; typedef LONG_PTR SIZE_T;
void *malloc(size_t size); void free(void *ptr);
DWORD GetWindowThreadProcessId(DWORD hWnd, LPDWORD lpdwProcessId); DWORD OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId); BOOL CloseHandle(DWORD hObject);
int __stdcall MultiByteToWideChar(int cp, int flag, const char* src, int srclen, wchar_t* dst, int dstlen); int __stdcall WideCharToMultiByte(int cp, int flag, wchar_t *src, int srclen, char* dst, int dstlen, const char* defchar, int* used); int __stdcall WriteProcessMemory( void *hProcess,void *lpBaseAddress,void *lpBuffer,size_t nSize,size_t *lpNumberOfBytesWritten);
BOOL ReadProcessMemory( DWORD hProcess, DWORD lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead ); ]]
local PROCESS_VM_READ = 0x0010
local export = {} export.set_buffer_size = function(size) export.buffer_raw = nil collectgarbage() export.buffer_raw = ffi.gc(C.malloc(size), C.free) export.buffer_size = size end export.set_buffer_size(128)
local ReadMemory = function (address, size) end do local PID = ffi.new('DWORD[1]') ReadMemory = function (address, size) if size > export.buffer_size then export.set_buffer_size(size) end
user.GetWindowThreadProcessId(workwindow(), PID) log("PID[0]: " .. PID[0]) local process = C.OpenProcess(PROCESS_VM_READ,true, PID[0]);
if process > 0 then local result = C.ReadProcessMemory(-1, address, export.buffer_raw, size, nil) C.CloseHandle(process) if result ~= 0 then return true end end log('Process not opened') return nil, -2 end end
export.char = function (address, lenght) if ReadMemory(address, lenght) then export.buffer = ffi.cast("char *", export.buffer_raw) return export.buffer[0] end return nil end
export.byte = function (address, lenght) if ReadMemory(address, lenght) then export.buffer = ffi.cast("BYTE *", export.buffer_raw) return export.buffer[0] end return nil end
export.short = function (address, lenght) if ReadMemory(address, lenght*2) then export.buffer = ffi.cast("short *", export.buffer_raw) return export.buffer[0] end return nil end
export.word = function (address, lenght) if ReadMemory(address, lenght*2) then export.buffer = ffi.cast("WORD *", export.buffer_raw) return export.buffer[0] end return nil end
export.int = function (address, lenght) if ReadMemory(address, lenght*4) then export.buffer = ffi.cast("int *", export.buffer_raw) return export.buffer[0] end return nil end
export.dword = function (address, lenght) if ReadMemory(address, lenght*4) then export.buffer = ffi.cast("DWORD *", export.buffer_raw) return export.buffer[0] end return nil end
export.float = function (address, lenght) if ReadMemory(address, lenght*4) then export.buffer = ffi.cast("float *", export.buffer_raw) return export.buffer[0] end return nil end
export.double = function (address, lenght) if ReadMemory(address, lenght*8) then export.buffer = ffi.cast("double *", export.buffer_raw) return export.buffer[0] end return nil end
export.string = function (address, lenght) if ReadMemory(address, lenght) then export.buffer = ffi.cast("char *", export.buffer_raw) return ffi.string(export.buffer, lenght) end return nil end
--unicode to ansistring function w2astring (wString)
end
export.unicode = function (address, lenght) if export.string(address, lenght) then local wString = ffi.cast("short *", export.buffer_raw) local len = ffi.C.WideCharToMultiByte(0, 0, wString, -1, nil, 0, nil, nil) local aString = ffi.new("char[?]",len) ffi.C.WideCharToMultiByte(0, 0, wString, -1, aString, lenght, nil, nil) return ffi.string(aString) end return nil end
что в логе теперь?
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
DarkMaster |
19.2.2024, 16:42
|
Модератор UOPilot
Сообщений: 9.573
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 28548
Пользователь №: 11.279
|
Код --lua log"clear"
local ffi = require("ffi") local C = ffi.C local user = ffi.load('User32')
--bind WINAPI ffi.cdef [[ typedef int BOOL; typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; typedef void * LPVOID; typedef const void * LPCVOID; typedef DWORD * LPDWORD; typedef void * PVOID; typedef PVOID HANDLE; typedef HANDLE HWND; typedef long LONG_PTR; typedef LONG_PTR SIZE_T;
void *malloc(size_t size); void free(void *ptr);
DWORD GetWindowThreadProcessId(DWORD hWnd, LPDWORD lpdwProcessId); DWORD OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId); BOOL CloseHandle(DWORD hObject);
int __stdcall MultiByteToWideChar(int cp, int flag, const char* src, int srclen, wchar_t* dst, int dstlen); int __stdcall WideCharToMultiByte(int cp, int flag, wchar_t *src, int srclen, char* dst, int dstlen, const char* defchar, int* used); int __stdcall WriteProcessMemory( void *hProcess,void *lpBaseAddress,void *lpBuffer,size_t nSize,size_t *lpNumberOfBytesWritten);
BOOL ReadProcessMemory( DWORD hProcess, DWORD lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead ); ]]
local PROCESS_VM_READ = 0x0010
local export = {} export.set_buffer_size = function(size) export.buffer_raw = nil collectgarbage() export.buffer_raw = ffi.gc(C.malloc(size), C.free) export.buffer_size = size end export.set_buffer_size(128)
local ReadMemory = function (address, size) end do local PID = ffi.new('DWORD[1]') ReadMemory = function (address, size) if size > export.buffer_size then export.set_buffer_size(size) end
user.GetWindowThreadProcessId(workwindow(), PID) local process = C.OpenProcess(PROCESS_VM_READ,true, PID[0]);
if process > 0 then local result = C.ReadProcessMemory(process, address, export.buffer_raw, size, nil) C.CloseHandle(process) if result ~= 0 then return true end end log('Process not opened') return nil, -2 end end
export.char = function (address, lenght) if ReadMemory(address, lenght) then export.buffer = ffi.cast("char *", export.buffer_raw) return export.buffer[0] end return nil end
export.byte = function (address, lenght) if ReadMemory(address, lenght) then export.buffer = ffi.cast("BYTE *", export.buffer_raw) return export.buffer[0] end return nil end
export.short = function (address, lenght) if ReadMemory(address, lenght*2) then export.buffer = ffi.cast("short *", export.buffer_raw) return export.buffer[0] end return nil end
export.word = function (address, lenght) if ReadMemory(address, lenght*2) then export.buffer = ffi.cast("WORD *", export.buffer_raw) return export.buffer[0] end return nil end
export.int = function (address, lenght) if ReadMemory(address, lenght*4) then export.buffer = ffi.cast("int *", export.buffer_raw) return export.buffer[0] end return nil end
export.dword = function (address, lenght) if ReadMemory(address, lenght*4) then export.buffer = ffi.cast("DWORD *", export.buffer_raw) return export.buffer[0] end return nil end
export.float = function (address, lenght) if ReadMemory(address, lenght*4) then export.buffer = ffi.cast("float *", export.buffer_raw) return export.buffer[0] end return nil end
export.double = function (address, lenght) if ReadMemory(address, lenght*8) then export.buffer = ffi.cast("double *", export.buffer_raw) return export.buffer[0] end return nil end
export.string = function (address, lenght) if ReadMemory(address, lenght) then export.buffer = ffi.cast("char *", export.buffer_raw) return ffi.string(export.buffer, lenght) end return nil end
export.unicode = function (address, lenght) if export.string(address, lenght) then local wString = ffi.cast("short *", export.buffer_raw) local len = ffi.C.WideCharToMultiByte(0, 0, wString, -1, nil, 0, nil, nil) local aString = ffi.new("char[?]",len) ffi.C.WideCharToMultiByte(0, 0, wString, -1, aString, lenght, nil, nil) return ffi.string(aString) end return nil end
Пробуй. Там читалось окно пилота =) я тестил то на пилоте им же и память выделял - потому и шуршало. Байпас убрать забыл.
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
фонарик |
19.2.2024, 16:48
|
Apprentice
Сообщений: 157
Регистрация: 23.11.2011 Группа: Пользователи Наличность: 13
Пользователь №: 14.305
|
Цитата(DarkMaster @ 19.2.2024, 16:42) Пробуй. Там читалось окно пилота =) я тестил то на пилоте им же и память выделял - потому и шуршало. Байпас убрать забыл. РАААБОТАЕТТ (IMG: style_emoticons/default/yahoo.gif) Большущее Вам спасибо, DarkMaster. Вы настоящий волшебник (IMG: style_emoticons/default/cool.gif) Только, вот, как бы это объяснить (IMG: style_emoticons/default/unsure.gif) Такое количество строчек в коде на древнем непонятном языке, когда сам по себе скрипт небольшой... Можно как-то ваше заклинание обернуть в какой-нибудь файл и просто его подключать? Чисто чтобы не демотивироваться при изменении и дополнении скрипта (IMG: style_emoticons/default/biggrin.gif) Можете посоветовать как так сделать? Если так можно и оно будет так работать конечно.
|
|
|
|
фонарик |
19.2.2024, 17:05
|
Apprentice
Сообщений: 157
Регистрация: 23.11.2011 Группа: Пользователи Наличность: 13
Пользователь №: 14.305
|
Цитата(DarkMaster @ 19.2.2024, 16:50) Это больше спасибо cirus и Cockney, которых я сегодня задолбал с типами данных) Спасибо всему совету магистров всем всем огромное (IMG: style_emoticons/default/thanks.gif) Может проглядели мой вопрос выше про перемещение заклинания кода с волшебными функциями вне тела самого скрипта? (IMG: style_emoticons/default/rolleyes.gif)
|
|
|
|
DarkMaster |
19.2.2024, 18:52
|
Модератор UOPilot
Сообщений: 9.573
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 28548
Пользователь №: 11.279
|
А теперь немного о быдло коде =) Меня очень сильно вымораживает два вызова WideCharToMultiByte и два буфера для него. Вполне очевидно, что астрока будет короче wстроки и если использовать буфер wстроки, то в него поместится астрока. Но функция прямо запрещает использовать один и тот же указатель. Городить из-за этого второй буфер, увеличение при необходимости, функцию ресайза, передавать управление буфером пользователю, чтобы в случае необходимости его грохал, объяснять чем различаются два буфера ну совсем не хочется. Насколько быдлячеством будет использование указателя со смещением -1 от wстроки?(память естественно будет аллоцирована)
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|