Re: AHK: Передать структуру
524 * 2 это верное смещения id.
Смещение-то верное, но подсчёт неверный, просто попали пальцем в небо.
Указатель на строку ничем не отличается от любого другого указателя.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Чтобы отправить ответ, вы должны войти или зарегистрироваться
524 * 2 это верное смещения id.
Смещение-то верное, но подсчёт неверный, просто попали пальцем в небо.
Указатель на строку ничем не отличается от любого другого указателя.
Почему в небо, я же смог подсчитал Юникод структуру как-то. А как их передавать указатели на строку?
я же смог подсчитал Юникод структуру как-то
Как подсчитали? Я и предлагал показать, как именно. Использование 524 * 2 говорит о том, что не понимаете, как считать. Откуда это 524 взялось, и почему его нужно на 2 умножать?
А как их передавать указатели на строку?
Через NumPut по нужному смещению:
NumPut(&str, &struct + offset)
wchar_t - это Юникод строка, * 2. А 524 я же писал уже:
• По смещению 0 есть UInt.
• По смещению 4 есть 520 длинных массивов символов.
• По смещению 524 есть UInt.
А про указатели я не понял, а как узнать их смещения.
И как передать 0 тут:
NumPut(&str, &struct + offset)
* 2 - это Юникод строка. А 524 я же писал уже:
• По смещению 0 есть UInt.
• По смещению 4 есть 520 длинных массивов символов.
• По смещению 524 есть UInt.
Это всё неверно, кроме По смещению 0 есть UInt.
И зачем нужно 524 на 2 умножать? Почему 520, ещё можно понять, но почему 524? Четвёрку-то зачем?
А про указатели я не понял, а как узнать их смещения.
Посчитать, как я пытался показать, но вы не захотели разбираться.
И как передать 0 тут
Ноль вообще передавать не нужно, изначально вся структура заполнена нулями, причём у вас зачем-то два раза подряд.
но почему 524?
В справке же написанно:
The second member is at offset 0 plus the size of the first member (typically 4).
Ноль вообще передавать не нужно, изначально вся структура заполнена нулями
А если вместо 0 нужно указать имя целвого процесса szTargetProcessExeFileName? То как в таком случае передать указатель? Если это возможно, конечно.
И как посчитать смещения указателя, вы не говорили.
The second member is at offset 0 plus the size of the first member (typically 4).
А как это объясняет, зачем нужно 4 на два умножать?
То как в таком случае передать указатель?
Как выше показал:
NumPut(&str, &struct + offset)
str это переменная со строкой, struct — структура, в которую передаём, offset — смещение.
И как посчитать смещения указателя, вы не говорили.
Смещение указателя ничем не отличается от остальных смещений, считается так же, во всяком случае для 32-битных процессов.
DllCall("ZeroMemory", "Ptr", &ParamStruct, "UInt", 540 * 2)
Это, кстати, тоже неверно.
зачем нужно 4 на два умножать?
Где такое написанно, я писал 524 * 2.
str это переменная со строкой
Какая-же это переменная - это указатель в вашем примере, а если там нужно указать строку, а не 0, то как ее передать?
Это, кстати, тоже неверно.
Что неверного, в заполнении нулями блока памяти?
Где такое написанно, я писал 524 * 2.
Ну, там же четвёрка лишняя. Строка занимает 520*2, она находится по смещению 4. Всего получается 4 + 520*2.
Какая-же это переменная - это указатель, а если там нужно указать строку, а не 0, то как ее передать numput'ом можно?
Вот прямо, как написано, так и передавайте, всё будет ок.
Что неверного, в заполнении нулями структуры?
Так заполнения не происходит, функции ZeroMemory не существует.
Строка занимает 520*2
Так я про id смещение, оно находится на 524 * 2.
Вот прямо, как написано, так и передавайте
Так как numput может передавать строки? Не пойму ничего.
Так я про id смещение, оно находится на 524 * 2.
Да, но почему, вы объяснить не можете. А если можете, значит такой вопрос
Так вроде структуры отличаются, смещения строки одинаковые, а дальше где должно быть id идет
у вас не должен возникнуть.
Так как numput может передавать строки?
Через знак & — это значит адрес переменной.
Хорошо, спасибо, буду разбираться. Пока нету вопросов.
Посчитал смещение для:
wchar_t* szTargetProcessExeFileName;
Оно находятся на 522 * 2. Это понятно, т.к. wchar_t имеет 2 байта размер. Но почему dword id находится на 524 * 2, если его размер является 4 байта? Это как-то связанно с Юникод структурой получается?
По-моему, вы опять гадаете. Распишите, сколько байтов занимает каждое поле, по-крайней мере, как вы это понимаете.
первое поле 0 байт.
второе 520 * 2 (умножить на 2 - это юникод строка, она в два раза больше анси).
третье 2 байта.
четвертое уже непонятно.
Вопрос невнимательно прочитали
сколько байтов занимает каждое поле
Поле не может занимать 0 байт.
Тогда:
4 байта.
520 * 2 байт.
2 байта.
4 байта.
struct INJECTIONDATA
{
DWORD LastErrorCode;
wchar_t szDllPath[MAX_PATH * 2];
wchar_t* szTargetProcessExeFileName;
DWORD ProcessID;
INJECTION_MODE Mode;
LAUNCH_METHOD Method;
DWORD Flags;
DWORD hHandleValue;
HINSTANCE hDllOut;
};
А почему третье два? Это указатель (адрес) переменной со строкой. Для 32 битных процессов указатели занимают 4 байта, для 64 битных 8.
По вашей ссылке смотрел: https://docs.microsoft.com/en-us/cpp/cp … om=vs-2019. Ориентировался на эту надпись: wchar_t 2 __wchar_t 0 to 65,535
Это имеет отношение ко второму полю, там указано, сколько занимает один wchar_t, действительно 2 байта, именно поэтому мы умножаем 520 (количество символов в строке) на два.
В третьем поле вы видите звёздочку, это значит указатель.
То-есть во втором поле мы передаём непосредственно саму строку с помощью StrPut(), а в третьем адрес строки с помощью NumPut().
Так проверьте, вот, может не очень правильный скрипт, но смещения работают, три первых поля я не гадал, а дальше да, вопросы уже, но я все-равно подобрал их исходя из файла ошибок.
#NoEnv
File := "test_.dll"
str := "test.exe"
WinGet, id, PID, ahk_exe test.exe
hModule := DllCall("LoadLibrary", "Str", "gh_injector.dll", "Ptr")
;msgbox % hModule
InjectW := DllCall("GetProcAddress", "Ptr", hModule, "Astr", "InjectW", "Ptr")
;msgbox % InjectW
VarSetCapacity(ParamStruct, 542 * 2, 0)
NumPut(&str, ParamStruct + 522 * 2)
NumPut(id, ParamStruct, 524 * 2, "Uint")
NumPut(2, ParamStruct, 526 * 2, "Uint")
NumPut(0, ParamStruct, 528 * 2, "Uint") ; 0 - NtCreateThreadEx
StrPut(File, &ParamStruct + 4, "UTF-16")
DllCall(InjectW, "Ptr", &ParamStruct)
Я посчитал почему-то по справке, что szTargetProcessExeFileName = 2 байтам. И это оказалось правильным смещением, не знаю.
Неудобно смотреть в таком виде. Зачем вы всё умножаете на 2? Здесь на 2 умножается только 520, остальное складывается. Перепишите, всё будет понятно.
Так вроде:
#NoEnv
File := "test_.dll"
str := "test.exe"
WinGet, id, PID, ahk_exe test.exe
hModule := DllCall("LoadLibrary", "Str", "gh_injector.dll", "Ptr")
InjectW := DllCall("GetProcAddress", "Ptr", hModule, "Astr", "InjectW", "Ptr")
;msgbox % InjectW
VarSetCapacity(ParamStruct, 1084, 0)
NumPut(&str, ParamStruct + 1044)
NumPut(id, ParamStruct, 1048, "Uint")
NumPut(2, ParamStruct, 1052, "Uint")
NumPut(0, ParamStruct, 1056, "Uint") ; 0 - NtCreateThreadEx
StrPut(File, &ParamStruct + 4, "UTF-16")
DllCall(InjectW, "Ptr", &ParamStruct)
Так тоже неудобно. Во-первых, для наглядности (и во избежание ошибок) нужно добавлять поля в том порядке, в котором они идут в структуре. Во-вторых, лучше расписывать оффсеты подробно, т. е. вместо
NumPut(&str, &ParamStruct + 1044)
пишем
NumPut(&str, &ParamStruct + 4 + 520*2)
И так же для остальных полей.
Ну да, у меня заработал такой вариант, но и мой вариант тоже работает же, не знаю.
#NoEnv
File := "test_.dll"
str := "test.exe"
WinGet, id, PID, ahk_exe test.exe
hModule := DllCall("LoadLibrary", "Str", "gh_injector.dll", "Ptr")
InjectW := DllCall("GetProcAddress", "Ptr", hModule, "Astr", "InjectW", "Ptr")
;msgbox % InjectW
VarSetCapacity(ParamStruct, 1084, 0)
StrPut(File, &ParamStruct + 4, "UTF-16")
NumPut(&str, ParamStruct + 4 + 520*2)
NumPut(id, ParamStruct, 8 + 520*2, "Uint")
NumPut(2, ParamStruct, 12 + 520*2, "Uint")
NumPut(0, ParamStruct, 16 + 520*2, "Uint")
DllCall(InjectW, "Ptr", &ParamStruct)
Теперь почти всё правильно, но, во-первых, откуда взялось здесь 1084?
VarSetCapacity(ParamStruct, 1084, 0)
Во-вторых, для наглядности лучше так:
StrPut(File, &ParamStruct + 4, "UTF-16")
NumPut(&str, ParamStruct, 4 + 520*2)
NumPut(id , ParamStruct, 4 + 520*2 + 4, "Uint")
NumPut(2 , ParamStruct, 4 + 520*2 + 8, "Uint")
; NumPut(0 , ParamStruct, 4 + 520*2 + 12, "Uint")
Ноль передавать не нужно (но можно для наглядности).
мой вариант тоже работает же
Если работает, значит смещения указаны правильно (посчитайте, какие в моём, какие в вашем), просто неправильно записаны.
откуда взялось здесь 1084?
Это емкость переменной, если поставить меньше, ничего не заработает. Но я еще не посчитал ее.
Если работает, значит смещения указаны правильно
Да, смещения такие же, я их просто по-своему записывал. А так, вроде все работает, буду дальше учить структуры.
Представьте, что структура - это письменный стол, а члены структуры это ящики в столе в сантиметрах.
Ящик может быть пустой или полный, но он всё-равно занимает какое-то место.
Хорошо, спасибо.
Чтобы отправить ответ, вы должны войти или зарегистрироваться