Recent

Author Topic: Does anyone know how to execute the machine code using free pascal  (Read 4154 times)

TYDQ

  • Full Member
  • ***
  • Posts: 102
I am trying to execute the machine code when running the main program.I am attempting to read the machine code in the memory and then execute it.Futuremore,this machine code's parameters are uncertain.
Does anyone know how to execute the machine code using free pascal and not to use inline assembly?
Code: Pascal  [Select][+][-]
  1. unit tydqexecutable;
  2.  
  3. interface
  4.  
  5. uses tydqfs,uefi;
  6.  
  7. type tydq_file_segment=packed record
  8.                   segmentnamecount:byte;
  9.                   segmentcodecount:qword;
  10.                   end;
  11.      tydq_file_executable=packed record
  12.                      ftype:byte;
  13.                      farch:byte;
  14.                      fsegmentcount:qword;
  15.                      end;
  16. const tydq_arch_x64=$00;
  17.       tydq_arch_aa64=$01;
  18.       tydq_arch_loongarch64=$02;
  19. var machinestr:array[1..256] of WideChar;
  20.     machinecode:array[1..268435456] of byte;
  21.     machinelen:dword;
  22.  
  23. procedure tydq_execute_executable(edl:efi_disk_list;filename:PWideChar;parameter:PPointer;userlevel:byte;belonguserindex:qword);
  24.  
  25. implementation
  26.  
  27. procedure tydq_execute_executable(systemtable:Pefi_system_table;edl:efi_disk_list;filename:PWideChar;parameter:PPointer;userlevel:byte;belonguserindex:qword);[public,alias:'TYDQ_EXECUTE_EXECUTABLE'];
  28. var fsi:tydqfs_file;
  29.     partstr:PWideChar;
  30.     procnum,pos,i,j:natuint;
  31.     fe:tydq_file_executable;
  32.     fs:tydq_file_segment;
  33.     Bytecode:^PByte;
  34. begin
  35.  partstr:=tydq_fs_locate_fullpath(edl,filename); procnum:=tydq_fs_locate_diskindex(edl,filename);
  36.  position:=tydq_fs_file_position(edl,procnum,partstr);
  37.  fsi:=tydq_fs_file_info(edl,procnum,partstr);
  38.  Wstrfree(partstr);
  39.  if(fsi.fattribute=0) then
  40.   begin
  41.    efi_console_output_string(systemtable,'Error:Executable cannot be executed,Permission denied.'#10); exit;
  42.   end
  43.  else if(tydq_fs_byte_to_attribute_bool(fsi.fattribute)[1]=false) then
  44.   begin
  45.    efi_console_output_string(systemtable,'Error:file is not executable file,file cannot be executed.'#10); exit;
  46.   end
  47.  else
  48.   begin
  49.    dp^.ReadDisk(dp,bp^.Media^.MediaId,position+sizeof(tydqfs_file),sizeof(tydq_file_executable),fe);
  50.    ByteCode:=allocmem(fe.fsegmentcount div sizeof(natuint)*sizeof(Pbyte));
  51.    for i:=1 to fe.fsegmentcount div sizeof(natuint) do
  52.     begin
  53.      dp^.ReadDisk(dp,bp^.Media^.MediaId,position+sizeof(tydqfs_file)+sizeof(tydq_file_executable)+(i-1)*sizeof(natuint),sizeof(natuint),pos);
  54.      dp^.ReadDisk(dp,bp^.Media^.MediaId,position+sizeof(tydqfs_file)+pos,sizeof(tydq_file_segment),fs);
  55.      dp^.ReadDisk(dp,bp^.Media^.MediaId,position+sizeof(tydqfs_file)+pos+sizeof(tydq_file_segment),
  56.      fs.segmentnamecount,machinestr);
  57.      dp^.ReadDisk(dp,bp^.Media^.MediaId,position+sizeof(tydqfs_file)+pos+sizeof(tydq_file_segment)+fs.segmentnamecount,
  58.      fs.segmentcodecount,machinecode);
  59.      (ByteCode+i-1)^:=allocmem(fs.segmentcodecount*sizeof(byte));
  60.      for j:=1 to fs.segmentcodecount do
  61.       begin
  62.        ((ByteCode+i-1)^+j-1)^:=machinecode[j];
  63.       end;
  64.     end;
  65.    for i:=fe.fsegmentcount div sizeof(natuint) downto 1 do Freemem((ByteCode+i-1)^);
  66.    Freemem(ByteCode);
  67.   end;
  68. end;
  69.  
  70. end.
« Last Edit: June 18, 2024, 03:52:50 am by TYDQ »

TRon

  • Hero Member
  • *****
  • Posts: 3623
Re: Does anyone know how to execute the machine code using free pascal
« Reply #1 on: June 17, 2024, 06:03:40 pm »
I could tell you exactly how to do that for Amiga.... but I am guessing that is not your target. Please do share because the answer is not a universal one (if possible at all).

Futuremore,this machine code's parameters are uncertain.
I just noticed this (Initially overlooked). How do you suggest to make that happen ?
« Last Edit: June 17, 2024, 06:18:54 pm by TRon »
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

trexet

  • New Member
  • *
  • Posts: 37
Re: Does anyone know how to execute the machine code using free pascal
« Reply #2 on: June 17, 2024, 07:14:48 pm »
AFAIR memory pages containing data are protected from execution (NX flag)

MarkMLl

  • Hero Member
  • *****
  • Posts: 8012
Re: Does anyone know how to execute the machine code using free pascal
« Reply #3 on: June 17, 2024, 09:56:30 pm »
AFAIR memory pages containing data are protected from execution (NX flag)

OP is doing himself a great disservice by not putting enough context at the start of each of his threads.

The "correct" way is to have the code address resolved as a library entry point by the linker.

The "classical" way, where that is not possible, would be a variant record where in one case the field represents a number which can be filled by computation, and in another represents a pointer to a parameterless procedure.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

TYDQ

  • Full Member
  • ***
  • Posts: 102
Re: Does anyone know how to execute the machine code using free pascal
« Reply #4 on: June 18, 2024, 03:48:35 am »
AFAIR memory pages containing data are protected from execution (NX flag)

OP is doing himself a great disservice by not putting enough context at the start of each of his threads.

The "correct" way is to have the code address resolved as a library entry point by the linker.

The "classical" way, where that is not possible, would be a variant record where in one case the field represents a number which can be filled by computation, and in another represents a pointer to a parameterless procedure.

MarkMLl
So how to resolve the machine code address as a library entry point(Because the whole code exceeds the limit of forum,it can't be published on this form)?

440bx

  • Hero Member
  • *****
  • Posts: 4730
Re: Does anyone know how to execute the machine code using free pascal
« Reply #5 on: June 18, 2024, 05:18:24 am »
I am trying to execute the machine code when running the main program.I am attempting to read the machine code in the memory and then execute it.Futuremore,this machine code's parameters are uncertain.
Does anyone know how to execute the machine code using free pascal and not to use inline assembly?
It's actually fairly simple but, you need to provide some critical information which is missing in your post.

The most important thing is, is the code you want to execute position independent ? IOW, code that can be loaded anywhere in the address space and _not_ require any "adjustments" depending on the address where it's loaded.

For code that is PIC, it's downright trivial.  Allocate a block of memory (properly aligned is a good idea), ensure the attributes are read/write/execute (or read/execute after you've written the instructions to it).  As far as executing the code, it's just as simple, typecast the pointer to the block that contains the instructions as a function or procedure (if you do that, put a "ret" at the end.)

if the code is not PIC then you need to apply relocations. In that case there should be a relocations table somewhere in the file that contains the code (PE files have a relocations directory for that purpose.)  Applying the relocations is fairly easy but, it is an additional step and, of course, it must be done correctly.

If you want to see a complete example of how it's done, look at Zydis' EncodeFromScratch example.  It's in C but easy to port to Pascal (I ported it but, my version uses my API definitions therefore without those, it's not compilable.)

HTH.


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 16154
  • Censorship about opinions does not belong here.
Re: Does anyone know how to execute the machine code using free pascal
« Reply #6 on: June 18, 2024, 07:09:41 am »
https://www.delphibasics.info/home/delphibasicssnippets

Contains a lot of - old and win32 centric - code to execute parts of code, such that the existing external code can work on your behalf.
Most of the tricks you find there will not easily work nowadays.
If I smell bad code it usually is bad code and that includes my own code.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8012
Re: Does anyone know how to execute the machine code using free pascal
« Reply #7 on: June 18, 2024, 09:12:08 am »
So how to resolve the machine code address as a library entry point(Because the whole code exceeds the limit of forum,it can't be published on this form)?

Haven't a clue. Read the manuals for whatever linker you're using: you've not told us.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

TYDQ

  • Full Member
  • ***
  • Posts: 102
Re: Does anyone know how to execute the machine code using free pascal
« Reply #8 on: June 18, 2024, 09:20:51 am »
So how to resolve the machine code address as a library entry point(Because the whole code exceeds the limit of forum,it can't be published on this form)?

Haven't a clue. Read the manuals for whatever linker you're using: you've not told us.

MarkMLl
Hmm......I have not have a linker build on my OS.However,uefi gives a way to execute the machine code.I will look up UEFI Documentation for executing machine code.

TRon

  • Hero Member
  • *****
  • Posts: 3623
Re: Does anyone know how to execute the machine code using free pascal
« Reply #9 on: June 18, 2024, 09:44:34 am »
So how to resolve the machine code address as a library entry point(Because the whole code exceeds the limit of forum,it can't be published on this form)?

Haven't a clue. Read the manuals for whatever linker you're using: you've not told us.

MarkMLl
Hmm......I have not have a linker build on my OS.However,uefi gives a way to execute the machine code.I will look up UEFI Documentation for executing machine code.
UEFI uses a custom toolchain... but 8 posts for a little piece of sane information ... I am out. The internet is your friend.
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

MarkMLl

  • Hero Member
  • *****
  • Posts: 8012
Re: Does anyone know how to execute the machine code using free pascal
« Reply #10 on: June 18, 2024, 09:59:36 am »
Hmm......I have not have a linker build on my OS.However,uefi gives a way to execute the machine code.I will look up UEFI Documentation for executing machine code.

Are you seriously trying to tell us that you're trying to write a development tool without already being intimately familiar with the target system's documentation?

What the Hell are you trying to do here- throw ideas in the air at random and see if you can get everybody else to do the work for you?

There's about one developer in a million who has any interest whatsoever in UEFI. Half of those are security researchers, the other half... aren't. At one point I did a fair amount of work at the system startup level (custom boot ROMs on a custom x86 board transferring control to a custom microkernel) but I'm long out of that and have a lot of other stuff on my plate.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 16154
  • Censorship about opinions does not belong here.
Re: Does anyone know how to execute the machine code using free pascal
« Reply #11 on: June 18, 2024, 10:24:51 am »
Code: [Select]
[quote]I am attempting to read the machine code in the memory and then execute it. On my previous link there are many examples for such - dubious - code!
If I smell bad code it usually is bad code and that includes my own code.

TYDQ

  • Full Member
  • ***
  • Posts: 102
Re: Does anyone know how to execute the machine code using free pascal
« Reply #12 on: June 18, 2024, 11:04:53 am »
So how to resolve the machine code address as a library entry point(Because the whole code exceeds the limit of forum,it can't be published on this form)?

Haven't a clue. Read the manuals for whatever linker you're using: you've not told us.

MarkMLl
Hmm......I have not have a linker build on my OS.However,uefi gives a way to execute the machine code.I will look up UEFI Documentation for executing machine code.
UEFI uses a custom toolchain... but 8 posts for a little piece of sane information ... I am out. The internet is your friend.
UEFI Specification give me a way to execute machine code with UEFI API.

TYDQ

  • Full Member
  • ***
  • Posts: 102
Re: Does anyone know how to execute the machine code using free pascal
« Reply #13 on: June 18, 2024, 11:05:44 am »
Code: [Select]
[quote]I am attempting to read the machine code in the memory and then execute it. On my previous link there are many examples for such - dubious - code!
Yeah,I will read your link you posted to me.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8012
Re: Does anyone know how to execute the machine code using free pascal
« Reply #14 on: June 18, 2024, 11:29:22 am »
UEFI uses a custom toolchain... but 8 posts for a little piece of sane information ... I am out. The internet is your friend.

Hmm. https://wiki.osdev.org/UEFI points at a couple of toolchains, using GCC or LLVM. Certainly in the GCC case that almost certainly implies use of the standard linker even if there is some subsequent operation to prepare a final file, so even if this is not a "custom toolchain" per se it would be reasonable to expect OP to already be familiar with the linker syntax and- in particular- the scripts that drive it.

Subject to writing custom initialisation code etc., FPC should be able to do the job. Or rather, OP should be able to do the job using FPC >:-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018