Столкнулся я с проблемой изменения кода функции в целях оптимизации (прошу прощения за си-стиль):
static inline bool ECX_to_EBX(void *ptr) {
map<byte*, byte> ecxs;
ecxs[(((byte*)ptr) + 18)] = 0xBB;
ecxs[(((byte*)ptr) + 67)] = 0x5D;
ecxs[(((byte*)ptr) + 69)] = 0x53;
size_t wr;
for (map<byte*, byte>::iterator pair_item = ecxs.begin(); pair_item != ecxs.end(); ++pair_item)
{
WriteProcessMemory(GetCurrentProcess(), pair_item->first, &pair_item->second, sizeof(byte), (SIZE_T*)&wr);
if (wr == 0) return true;
#ifdef LOG
else MessageBoxA(0, "", "replaced", 0);
#endif
}
return 0;
}
где в ptr
ожидается указатель на конкретную функцию, которую я уже разобрал на ассемблерные составляющие и хочу немного подкорректировать (заменить регистр ECX на EBX). Эта конкретная функция выглядит так:
struct MyClass{
static void MyFunc();
}
Передаю ее в качестве аргумента:
Utils::ECX_to_EBX(MyClass::MyFunc);
Смотрю в памяти, а там не то. Оказывается, что MyClass::MyFunc дает указатель на jmp MyProgram.MyClass::MyFunc
вместо указателя на само тело функции. Собственно вопрос, как получить указатель на первый байт тела (без вычисления относительного адреса относительно jmp) и почему я получаю указатель на jmp вместо него?
Это особенность компилятора visual-c++ или какие-то ключи компиляции?
На MinGW я такого казуса не припомню
как получить указатель на первый байт тела
При наличии полных отладочных символов (компоновка с /DEBUG:FULL
для VS 2017+) как-то так:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <windows.h>
#include "DbgHelp.h"
#pragma comment(lib, "Dbghelp.lib")
struct Function {
const char* name;
uintptr_t address;
bool success;
};
BOOL CALLBACK EnumSymProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID context) {
Function* pfstruct = (Function*)context;
if (strcmp(pSymInfo->Name, pfstruct->name) == 0) {
pfstruct->address = pSymInfo->Address;
pfstruct->success = true;
return FALSE; //закончить поиск
}
return TRUE; //продолжить поиск
}
bool GetFunctionAddress(const char* fname, uintptr_t& resultvar) {
bool ret;
Function fstruct;
fstruct.name = fname;
fstruct.address = 0;
fstruct.success = false;
HANDLE hProcess = GetCurrentProcess(); //текущий процесс
char Mask[] = "*!"; //искать среди всех модулей
BOOL status;
status = SymInitialize(hProcess, NULL, TRUE); //загрузка символов
if (status == FALSE)
{
printf("SymInitialize failed. Error code: %d\n", GetLastError());
return false;
}
//поиск символов
if (SymEnumSymbols(hProcess, 0, Mask, &EnumSymProc, (void*)&fstruct))
{
if (fstruct.success != false) {
resultvar = fstruct.address;
ret = true;
}
else {
printf("Symbol [%s] not found\n", fname);
ret = false;
}
}
else
{
printf("SymEnumSymbols failed. Error code: %d\n", GetLastError());
ret = false;
}
SymCleanup(hProcess);
return ret;
}
//**********************************
void Func() {
printf("Hello, World!\n");
}
int main(int argc, char **argv)
{
uintptr_t p;
if (GetFunctionAddress("Func", p) != false) {
//можно привести p к нужному типу и использовать...
}
return 0;
}
и почему я получаю указатель на jmp вместо него
Трудно сказать. Скорее всего, вы делаете что-то не то. Обычно, когда необходимо работать с неким куском кода как с машинным кодом, целесообразно реализовать его полностью ассемблерной вставкой, как например здесь. Это гарантирует, что формат машинного кода будет наиболее близок к тому, что вы ожидаете.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть класс в котором есть вот такая переменная
Нужно подключить SFML для работы в VS Code на WindowsНикакой адекватной информации не нашел, разве что для Linux
Не совсем могу понять как в шестой строке функция передаётся в качестве параметраКак я понял, код string(*fun)() должен обьявлять указатель fun, которому...
Составил небольшой примерКомпилятор не может найти тип ref как возвращаемое значение метода getA()