Forum > Spanish

al crear una función: tengo la ristra de opcodes, pero no puedo pegarla

(1/2) > >>

AMonAmi:
Tengo preparada una lista de  opcodes,  digamos   

ffCode: TByte ,

que tengo que "pegar" a una

 function F(x,y: Double): Double,

 pero no me deja usar soluciones como   @F:= @ffcode,  o @F:= ffCode , que ahora Lazarus
me sale con "Cannot assign values to addresses".  Qué puedo hacer?

BlueIcaro:
Hola, no acabo de entender que quieres decir, me imagino que quieres llamar a una función anónima.
Quizás esto te pueda ayudar: https://forum.lazarus.freepascal.org/index.php/topic,59468.0.html
Saludos
/BlueIcaro

AMonAmi:
Buelcaro:  no creo que tenga mucho que ver con funciones anónimas. Esto me ha ocurrido cuando estaba pasando una aplicación de Linux a Windows. Y hace diez años no ocurría eso. Gracias de todos modos.

440bx:
Es un poco complicado explicar come se hace pero tengo un ejemplo que es relativamente facil the comprender:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{ --------------------------------------------------------------------------- }{ @file                                                                       }{ Example on assembling a basic function returning `0x1337` in `rax`.         }   {$APPTYPE       CONSOLE} {$TYPEDADDRESS       ON}{$LONGSTRINGS       OFF} {$WRITEABLECONST    OFF}  { --------------------------------------------------------------------------- } program EncodeFromScratchA; uses  ZyDis,   winapi  ;  {$include Z900_zydis_inlines.inc} { --------------------------------------------------------------------------- } procedure ExpectSuccess(const InStatus : ZyanStatus); cdecl;const  EXIT_FAILURE = 1;    { defined in C's stdlib                                } var  Buffer : packed array[0..511] of char = #0; begin  sprintf(Buffer, 'Something failed: 0x08X', InStatus);   if ZYAN_FAILED(InStatus) then  begin    writeln(Buffer);     halt(EXIT_FAILURE);  end;end; { --------------------------------------------------------------------------- } type  PPZyanU8 = ^PZyanU8; procedure AppendInstruction            (             const InReq              : PZydisEncoderRequest;                   InoutBuffer        : PPZyanU8;                   InoutBuffer_length : PZyanUSize            ); cdecl;var  Instr_length : ZyanUSize = 0; begin  Assert(InReq              <> nil, 'InReg parameter cannot be nil');  Assert(InoutBuffer        <> nil, 'InoutBuffer cannot be nil');  Assert(InoutBuffer_length <> nil, 'InoutBufferLength cannot be nil');   Instr_length := InoutBuffer_length^;   ExpectSuccess    (     ZydisEncoderEncodeInstruction       (        InReq, InoutBuffer^, @Instr_length       )    );   inc(InoutBuffer^,        Instr_length);  dec(InoutBuffer_length^, Instr_length);end; { --------------------------------------------------------------------------- } function AssembleCode           (            InoutBuffer     : PZyanU8;            InBuffer_length : ZyanUSize           )         : ZyanUSize; cdecl;var  write_ptr        : PZyanU8   = nil;  remaining_length : ZyanUSize =   0;   req              : ZydisEncoderRequest = (); begin  Assert(InoutBuffer     <> nil, 'InoutBuffer cannot be nil');  Assert(InBuffer_length  > 0,   'InBuffer_length must be greater than zero');   write_ptr        := InoutBuffer;  remaining_length := InBuffer_length;   // Assemble `mov rax, 0x1337`.   RtlZeroMemory(@req, sizeof(req));   with req do  begin    mnemonic              := ZYDIS_MNEMONIC_MOV;    machine_mode          := ZYDIS_MACHINE_MODE_LONG_64;    operand_count         := 2;    operands[0].&type     := ZYDIS_OPERAND_TYPE_REGISTER;    operands[0].reg.value := ZYDIS_REGISTER_RAX;    operands[1].&type     := ZYDIS_OPERAND_TYPE_IMMEDIATE;    operands[1].imm.u     := $1337;  end;   AppendInstruction(@req, @write_ptr, @remaining_length);   // Assemble `ret`.   RtlZeroMemory(@req, sizeof(req));   with req do  begin    mnemonic     := ZYDIS_MNEMONIC_RET;    machine_mode := ZYDIS_MACHINE_MODE_LONG_64;  end;   AppendInstruction(@req, @write_ptr, @remaining_length);   result := InBuffer_length - remaining_length;end; { --------------------------------------------------------------------------- } type  pbyte       = ^byte; const  page_size   = $1000;  alloc_size  = page_size * 2; var  buffer      : pointer   = nil;   length      : ZyanUSize =   0;   sprintf_buf : packed array[0..511] of char = #0;   i           : integer; type  TFunction   = function () : ZyanU64; { will use the correct 64bit ABI } var  TheFunction : TFunction;  begin  // Allocate 2 pages of memory. We won't need nearly as much, but it simplifies  // re-protecting the memory to RWX later.   buffer := VirtualAlloc(nil, alloc_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);   // Assemble our function.   length := AssembleCode(buffer, alloc_size);   // Print a hex-dump of the assembled code.   for i := 0 to length - 1 do  begin    sprintf(sprintf_buf, '%02X ', pbyte(buffer)[i]);     write(sprintf_buf);  end;  writeln;    {$ifdef WIN64}         // original C source uses an O/S independent test     // ------------------------------------------------------------------------    // Align pointer to typical page size.     // this step is unnecessary because we used VirtualAlloc which aligns    // the allocation      // ------------------------------------------------------------------------    // Re-protect the heap region as RWX. Don't do this at home, kids!     // this step is unnecessary because we used VirtualAlloc with protection    // settings that already include execute, read and write      // ------------------------------------------------------------------------    // Create a function pointer for our buffer.     TheFunction := TFunction(buffer);     // ------------------------------------------------------------------------    { call the function                                                       }     writeln;    sprintf(sprintf_buf,           'Return value of JITed code: 0x%016llX',            TheFunction());                           { the JITed function    }    writeln(sprintf_buf);  {$endif}    writeln;  writeln;  writeln('press ENTER/RETURN to end this program');  readln;   { there does not seem to be a way to cause this message to be the last one  }  { in the Lazarus message window.                                            }   {$ifndef WIN64}    {$message warning this program has limited operation as a 32bit program   }  {$endif}end.  //// end of file// ----------------------------------------------------------------------------La funcion "AssembleCode" genera las instructiones binarias.  Esas instrucciones son ejecutadas en la linea 199.  Para ejecutarlas necessitas las definiciones en las lineas 152 a 156.

Puedes encontrar todo lo necessario para ejecutar el programa en la "thread" https://forum.lazarus.freepascal.org/index.php/topic,67665.msg521439.html#msg521439

En caso que estes interesado, es el ejemplo "105_EncodeFromScratchA"

ETA:

Todos los ejemplos requieren Windows.

Edson:

--- Quote from: AMonAmi on July 20, 2024, 11:33:17 am ---Tengo preparada una lista de  opcodes,  digamos   

ffCode: TByte ,

que tengo que "pegar" a una

 function F(x,y: Double): Double,

 pero no me deja usar soluciones como   @F:= @ffcode,  o @F:= ffCode , que ahora Lazarus
me sale con "Cannot assign values to addresses".  Qué puedo hacer?

--- End quote ---
Me parece que el nombre "Opcodes" no aporta mucho en el entendimiento de tu problema. Y sería bueno que expliques mejor lo que entiendes por "pegar".

Lo que yo veo declaraciones de una variable y una función. Y luego que intentas asignarle la dirección de una variable ¿a la dirección de una función?:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---@F:= @ffcode
Eso no tiene ningún sentido-. Y el mensaje del compilador es correcto. No se puede tomar la dirección de una función y escribir valores allí. Eso es sintácticamente erróneo. Y si en verdad quieres escribir datos en donde inicia el código de una función, eso sería código automodificable y va en contra de la seguridad de la aplicación.

Navigation

[0] Message Index

[#] Next page

Go to full version