Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   ASM incorrecto? (https://www.clubdelphi.com/foros/showthread.php?t=90503)

Reasen 27-06-2016 22:43:07

ASM incorrecto?
 
Buenas, me encuentro con un problema, traduciendo la función de: http://www.codeproject.com/Articles/...ng-Guide#BpMem
Tengo el siguiente error al querer compilar:
"E2116 Invalid combination of opcode and operands"

El error me ocurre en la línea: "push MemBpBeingDebugged"
Intente dejarlo exactamente igual pero algo falla y no encuentro el que, espero que le podáis echar un cable al asunto.

Mi source:

Código Delphi [-]

function DetectMemoryBP(): integer;
var
  pMem, pAllocation: pointer;
  SysInfo: TSystemInfo;
  oldprotect: dword;
  NullSize_T: SIZE_T;
label
  MemBpBeingDebugged;
begin
  NullSize_T := 0;
  pMem := nil;
  GetSystemInfo(SysInfo);
  oldprotect := 0;
  pAllocation := VirtualAlloc(nil, sysinfo.dwPageSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);

  if (pAllocation = nil) then
    result := 0;
  pMem := Pointer($C3);

  if VirtualProtect(pAllocation, sysinfo.dwPageSize, PAGE_EXECUTE_READWRITE or PAGE_GUARD, @oldprotect) = false then
    result := 0;

  try
    asm
        mov     EAX, pAllocation
        push    MemBpBeingDebugged
        jmp     EAX // Exception or execution, which shall it be :D?
    end;
  except
    VirtualFree(pAllocation, NullSize_T, MEM_RELEASE);
    result := 0;
    exit;
  end;

MemBpBeingDebugged:

  VirtualFree(pAllocation, NullSize_T, MEM_RELEASE);
  result := 1;

end;


Ejemplo de uso:
  if DetectMemoryBP > 0 then
    MessageBox(0, 'detectado', '', 0);

Ñuño Martínez 28-06-2016 13:30:46

Estás intentando meter en pila una posición de código ejecutable. No manejo ensamblador de los últimos micros, pero sospecho que no es tan fácil como hacer un "push label" por el tema del bloqueo de memorias, cachés y demás. De hecho es lo que te está diciendo el mensaje de error.

De todas formas, no entiendo qué quieres hacer. Un simple "GOTO MemBpBeingDebugged;" bastaría.

Reasen 28-06-2016 14:04:34

Ojalá bastara con un GOTO(JMP) pero no me da buenos resultados hacerlo de esa manera, intento traducir la función de C++ para crear una técnica anti-debug para Delphi como mencioné mas arriba.
Por lo que parece, lo suyo sería obtener la dirección/puntero de ese label pero ¿cómo se podría realizar esa técnica?

Ñuño Martínez 28-06-2016 20:27:02

Pues no se me ocurre otra cosa. :confused:

mamcx 28-06-2016 20:37:19

Siendo un completo ignorante de ASM, porque no ejecutas en C++ y usas un debugger que te muestre que ASM esta generando, y luego lo mismo en Delphi?

Reasen 28-06-2016 20:49:37

En C++_ASM se muestra una dirección que apunta a ese label de C++, lo que falta es calcular esa dirección del label en Delphi, ya que Delphi no lo hace automáticamente.
Es una dirección que varía dependiendo del ejecutable por lo que es necesario crear una función que lo calcule en tiempo de ejecución.

AgustinOrtu 28-06-2016 23:14:43

Yo tambien soy un ignorante mas, pero solo por curiosidad, que valor de retorno obtienes de la llamada a la funciones:

VirtualAlloc,
VirtualProtect

Porque si alguna falla (evalua a False), entonces no deberia ser seguro continuar con tu codigo. Deberias llamar a GetLastError, ya que estas funciones no elevan excepciones por si solas.

Otra cosa, en la parte final de tu codigo, podrias refactorizarlo porque estas repitiendo codigo. Ademas, no entiendo porque retornas un Integer cuando luego la usas como un Boolean:


Código Delphi [-]
function DetectMemoryBP: Boolean;
var
  pMem, pAllocation: Pointer;
  SysInfo: TSystemInfo;
  oldprotect: dword;
  NullSize_T: SIZE_T;
label
  MemBpBeingDebugged;
begin
  Result := False;
  NullSize_T := 0;
  pMem := nil;
  GetSystemInfo(SysInfo);
  oldprotect := 0;
  pAllocation := VirtualAlloc(nil, sysinfo.dwPageSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);

  if (pAllocation = nil) then
    Exit(False); // o podrias invocar a RaiseLastOsError 

  pMem := Pointer($C3);

  if not VirtualProtect(pAllocation, sysinfo.dwPageSize, PAGE_EXECUTE_READWRITE or PAGE_GUARD, @oldprotect) then
    Exit(False); // o podrias invocar a RaiseLastOsError 

  try
    asm
        mov     EAX, pAllocation
        push    MemBpBeingDebugged
        jmp     EAX // Exception or execution, which shall it be ?
    end;
  finally
    VirtualFree(pAllocation, NullSize_T, MEM_RELEASE);
  end;

  MemBpBeingDebugged:
  Result := True;
end;

Reasen 29-06-2016 01:20:42

Hola AgustinOrtu, gracias por pulir mi código, estos son los valores que me retornan VirtualAlloc y VirtualProtect
:::
VirtualProtect = True
VirtualAlloc = 0
:::
Dejo un screenshot de cómo se ven las 3 instrucciones de ASM con un compilador de C++ desde un debugger las cuales estoy intentando implementar en Delphi:

Se puede apreciar como apunta al label que está un poco mas abajo del código...
¿Una solución un poco sucia seria apuntar unos bytes mas abajo desde la posición que se encuentre X código?

AgustinOrtu 29-06-2016 04:11:38

Bueno como te decia, no soy un experto. Pero leyendo la documentacion de VirtualAlloc, lo que te devuelve es

Cita:

If the function succeeds, the return value is the base address of the allocated region of pages.
Esa direccion no te sirve para realizar el calculo de offset?

Reasen 29-06-2016 12:18:29

No se me ocurre otra manera que "HardCodearlo", pues no creo que sea una buena solución, quedaría inestable o sería difícil hacer cambios.


La franja horaria es GMT +2. Ahora son las 12:48:02.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi