Let's say I have a small block of machine code at address X, that's part of an EXE (PE). It contains all kind of instructions including those with relative addresses. How could I move this code to address Y without changing its behaviour? I don't want to write my own decompiler. Some existing library or a trick, maybe?
The standard thing to do in the 'old school' days is to leave your code at 'x', replace the first few bytes (say it was 3) with a jump to the new code. At the end of the new code you execute the code that you replaced at 'x', then jump back to 'x'+3
Generally impossible, but oblivious if the code is carefully written. See: position-independent code.
Related
I have come accross the idea to use pragmas to make PLC code as easy to re-configure from machine to machine depending on what a particular machine requires (they are very similar, but still require to some work to make for every new project). The machine as a whole can contain N units, then you would just remove certain parts if new project does not need it. My idea was:
VAR_GLOBAL
{attribute 'machinePart1'}
{attribute 'machinePart2'}
//{attribute 'machinePart3'} Lets say machine does not use attribute machinePart3
machineParts : BOOL; // dummy variable to add attributes
END_VAR
In the PLC code, I would then use conditional pragmas for code parts that require or don't require certain parts - you would determin which attribute exists by commenting out unnecessary ones.
In the PLC the parts of the machine that are not present would then be disregarded like this:
{IF hasattribute (variable: machineParts, 'machinePart3')}
//this code will not be executed
{END_IF}
{IF hasattribute (variable: machineParts, 'machinePart2')}
//this code will be executed
{END_IF}
{IF hasattribute (variable: machineParts, 'machinePart1')}
//this code will be executed
{END_IF}
So, my question is - is this a valid way to go about making a PLC code as easy to configure as possible? Does it affect efficency/CPU time? I havent looked deep into this, but I would assume the code is compiled, and for whatever conditional pragma the result is false, the code isn't complied and thus not present on the PLC itself when downloaded.
I would apply this to structures for machine parts and PLC code exectuion/function block instance creation.
Beckhoff already provides a solution for your requirements which is called variant management:
https://infosys.beckhoff.com/english.php?content=../content/1033/variant_management/6325752587.html&id=
This does not affect performance as the compiled code only includes the variant that you have chosen.
Jakob is right, there is already a variant management for the project level. And the link describes all necessary steps. The only thing to add here is a little advice from someone who has already fallen on his face with it several times. Be carefull with or rather just don't use the group feature (<=TC4024.20). The behaviour is really strange and very error-prone, from my point of view.
I have a problem. When the program reads a text file, it always get out of the line and crashed.
var f:text;
i,j,cs:byte;
a:array[0..10,0..10] of int64
begin
assign(f,'anything.txt');
reset(f);
cs:=0;
while eoln(f)=false do
begin
read(f,a[0,cs]);
inc(cs);
end;
close(f);
end.
Here is the content of anything.txt:
2 4 8 16
exitcode=201
You have not told us which compiler you are using.
In Delphi and Turbo Pascal which preceded it, run-time error 201 means "range check error". I don not still have Turbo Pascal installed but your program compiles and runs as a "console application" correctly in Delphi with only one minor change, namely to insert a semi-colon (';') after int64. It runs correctly whether the compiler has range-checking turned on or not.
It also runs correctly in FreePascal + Lazarus.
So, unless you are using a different compiler which also happens to have a run-time error code 201, your problem seems to be caused by something you have not included in your question. In any case you should learn to debug this kind of problem yourself. So:
Look up how to use use the debugger in your Pascal compiler. Place a breakpoint on the line inc(cs) e.g. by pressing F5and run the program. When it stops at the BP, place debug watches (using Ctrl-F5 in Delphi/TP) on the values of cs and a and observe the values carefully. Press F8 repeatedly to single step the program, and see if you can see where and why it goes wrong.
One possibility for what is causing your problem is that you are not reading the copy on anything.txt you think you are: because you don't include a path to the file in assign(f Windows will use the copy of anything.txt, if any, in whatever it thinks the current directory is. To avoid this, include the path to where the file is, as in
assign(f, 'C:\PascalData\Anything.Txt');
Also btw, you don't need to compare a boolean function (or expression) againt true or false as in
while eoln(f)=false do
Instead you can simply do
while not eoln(f) do
I wanna add custom helloworld syscall to FreeBSD. I used following link as my guide: http://members.tripod.com/s_mathur/bsdhowto.html In step 4 says: Modify the Make File to include sys_hello.c , etc and recompile the kernel! Which Make File? Where is it? and how to compile it and how call syscall hello?
The error that I faced with it, is:
init_sysent.o:(.data + 0x6638): undefined reference to 'sys_hello'
I think that it is because of my Make file, because I don't know I should modify which Make File.
I'm afraid you are not ready to do any kernel development and as such strongly suggest you refrain from it.
I don't know how you ended up on that guide, I have trouble finding it when I look for ways to add system calls to the FreeBSD kernel.
The guide has bits which are outdated and some which were always wrong.
You created a new file (sys_hello.c) but did not add it to the build process. Figuring out how to do that should be trivial.
1. pick a syscall which is always provided, like fork
2. find the file implementing it
3. grep the source tree for mentions of that file
4. profit
Performing the steps and getting the answer is left as an exercise for the reader.
int syshello(p, uap)
struct proc* p; struct syshello_args uap;
K&R C declaration? Just how old is this?
The first argument for several years now is struct thread *.
{
sprintf(uap->buf,"Hello"); /* fill the buffer with Hello */
Fundamentally wrong. Consider what happens if userspace passes a kernel address. Also this assumes shared address spaces to "work". The code should have used copyout. Except the code is additionally wrong by not having an argument allowing the userspace to say what the size is.
p->p_retval[0] = 0; /* set the return value of the system call*/
return 0;
}
As noted earlier, given your difficulty with figuring out what to do with the new file it is clear you are new to programming and as such you really should not touch the kernel until you grow.
In relationship to this thread, this is also what i am kind of trying to do but i have had a bit more leeway in this.
My problem is i am currently working on a defining program (for my ti-89 titanium) to write out the definitions of variables. However, considering i had indefinite amounts of variables to add, i thought using the define function over and over again would waste memory and processing power. So my thinking was Save the variable to another variable to be defined in a later portion of the program.
prompt x
lbl x_d_r
x_d_r->q:Goto def
lbl def
define expr(q)[1]=x
where x_d_r has no assigned value. So the program was supposed to use the defined string as a list value to be x. However the obvious error came about.
So i played around on the home screen and program screen for a bit and came across entry(1) and ans(1). See back on the ti-83 (or 84) i could basically go (If i remember correctly)
disp q*1
x->ans(1)
However ans(1) on a ti-89 titanium is based upon the last answer submitted to the homescreen. Even then, ans(1) or entry(1) gets replaced in the program by just that. Lucky me, i found a way to avoid this.
Prgm
expr(char(120)&char(22)&char(97)&char(110)&char(115)&char(40)&char(49)&char(41))
EndPrgm
For those that do not know, this is simply expressing x->ans(1) which is a way for the code to transmit ans(1) within a program without removing the code to say so.
But it still does not work as a value needs to be sent to the home screen in order for it to record properly. This is one of those advantages that the ti-84 or ti-83 i wish it still had on the titanium. So i have spent some time searching for ways how i can display values of q to the home screen from within a program.
So far i learned that functions when used straight from the home screen return the value of q to the same place. However i have no way of implementing this in an actual program as the function does not wish to transmit the value to the home screen, and its rather useless within the program.
Secondly i have found this website which details methods of such ways to return values to the homescreen. While method 1 seems to hold promise, i do not seem to have any way of accessing that folder/program. Most likely because it is one that he made and has not shared its location on the pdf. I do like the expr("q"&":stop"), but q is not evaluated out so maybe i would have to rework it somehow.
While this was happening, i thought some other ideas could be using the paste key within a program but i have no idea how to implement stuff found from getkey let alone how the second and grab buttons factor in.
Or i could somehow have the ans(1) look to someplace else other than the home screen. Preferably to the i/0 screen but maybe to some other list or data matrix.
Anybody have any ideas on how to relay a value to the homescreen be it through function, pasting or something, and have the program i defined earlier define it as a value?
UPDATE+1
Ok i am beginning to question if maybe i am making it more complex than it needs to be...
After all, i am only going for just x->x_d_r[1], which is already defined elsewhere. So does it beat x->q:Goto def
Lbl def
Define expr(q)=x
(Or something like that which calls to a history recording program to define values?)
in terms of processing speed and memory count?
Got it. See here for what i was really trying to do.
So as an explanation of what the main problem was again, i wanted to be able to post a string value of q to be defined by another value of x.
The expr( function is quite a powerful tool on the ti-89 and like the person in that other forum, underestimated it. See what the person was trying to do was
InputStr "Function:",f(x)
expr(f)→f(x)
And was later answered by reworking it as
InputStr "function", n
expr(n & "->f(x)")
The expression tool just simply expresses what is in the parentheses. So during break periods in school today, i reworked in my head thinking "What if i tried rewriting the parenthesis out so it reads Expr("x->"&String(q))?
Lo-and-behold it works. Tested it with the fuller version of define to get
td()
Prgm
Prompt X
x_d_r->q
expr("x->"&string(q)&"[1]")
Disp x_d_r[1]
Delvar x_d_r
EndPrgm
Tried, tested and true. Works all the way. See what i think is happening is that anything that is not within the quotes is evaluated immediately in an expression while the the quoted objects are simply expressed and added later in response to the "&" key. Furthermore it makes sense if i was to describe it more with english; "Express x to be stored into the string of q's respective table".
While for variables sake i would have to look into ways to make x_d_r local only to the program without compensating the fact that the x_d_r portion is not considered a store value when executing x_d_r->q. But knowing what i know now i could probably do
expr("q"+"x_d_r"&->a)
expr("x->"&string(a)-"q"&"[1]")
In order to bypass that problem.
I'm building a static binary out of several source files and libraries, and I want to control the order in which the functions are put into the resulting binary.
The background is, I have external code which is linked against offsets in this binary. Now if I change the source, all the offsets change because gcc may decide to order the functions differently, so I want to put the referenced functions at the beginning in a fixed order so their offsets stay unchanged...
I looked through ld's documentation but couldn't find anything about order of functions.
The only thing i found was -fno-toplevel-reorder which doesn't really help me.
There is really no clean and reliable way of forcing a function to a particular address (except for the entry function) or even forcing functions having a particular order (and if you could enforce the order that would still not mean that the addresses stay the same when the source is changed!).
The biggest problem that I see is that even if it may be possible to fix a function to some address, it will be sheer impossible to fix all of them to exactly the addresses that the already existing external program expects (assuming you cannot modify this program). If that actually worked, it would be total coincidence and sheer luck.
It might be almost easiest to provide trampolines at the addresses that the other program expects, and having the real functions (whereever they may be) pointed to by these. That would require your code to use a different base address, so the actual program code doesn't collide with the trampolines.
There are three things that almost work for giving functions fixed addresses:
You can place each function that isn't allowed to move in its proper section using __attribute__ ((section ("some name"))). Unluckily, .text always appears as the first section, so if anything in .text changes so the size is bumped over the 512 byte boundary, your offsets will change. By default (but see below) you can't get a section to start before .text.
The -falign-functions=n commandline option lets you align functions to a boundary. Normally this is something around 16 bytes. Now, you could choose a large value like for example 1024. That will waste an immense amount of space, but it will also make sure that as long as functions only change moderately, the addresses of the following functions will remain the same. Obviously it still does not prevent the compiler/linker from reordering entire blocks when it feels like it (though -fno-toplevel-reorder will prevent this at least partially).
If you are willing to write a custom linker script, you can assign a start address for each section. These are virtual memory addresses, not positions in the executable, but I assume the hard linking works with VMAs (based on the default image base) too. So that could kind of work, although with much trouble and not in a pretty way.
When writing your own linker script, you could also consider putting the functions that must not move into their own sections and moving these sections at the beginning of the executable (in front of .text), so changes in .text won't move your functions around.
Update:
The "gcc" tag suggests that you probably target *NIX, so again this is probably not going to help you, but... if you have the option to use COFF, dollar-sign sections might work (the info might be interesting for others, in any case).
I just stumbled across this today (emphasis mine):
The "$" character (dollar sign) has a special interpretation in section names in object files. When determining the image section that will contain the contents of an object section, the linker discards the "$" and all characters that follow it. Thus, an object section named .text$X actually contributes to the .text section in the image. However, the characters following the "$" determine the ordering of the contributions to the image section. All contributions with the same object-section name are allocated contiguously in the image, and the blocks of contributions are sorted in lexical order by object-section name. Therefore, everything in object files with section name .text$X ends up together, after the .text$W contributions and before the .text$Y contributions.
If the documentation does not lie (and if I'm not reading wrong), this means you should be able to pack all the functions that you want located in the front into one section .text$A, and everything else into .text$B, and it should do just that.
Build your code with -ffunction-sections -- this will place each function into its own section.
If you are using GNU-ld, the linker script gives you absolute control, but is a very platform-specific and somewhat painful solution.
A better solution might be to use the recent work on gold, which allows exactly the function ordering you are seeking.
A lot of it comes from the order the functions are in the file and the order the files are on the command line when you link.
Embed something in the code that your external code can find, a const structure with some ascii code and the address to functions perhaps, then no matter where the compiler puts the functions you can find them.
that or use the normal .dll or .so mechanisms, and not have to mess with it.
In my experience, gcc -O0 will fix the binary order of functions to match the order in the source code.
However as others have mentioned, even if the order is fixed, the offsets can change as you modify the source code or upgrade your toolchain.