Forum > Spanish
al crear una función: tengo la ristra de opcodes, pero no puedo pegarla
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