flat assembler
Message board for the users of flat assembler.

Index > Heap > "Discussion" from the "fixups?" thread

Goto page Previous  1, 2, 3  Next
Author
Thread Post new topic Reply to topic
Azu



Joined: 16 Dec 2008
Posts: 1160
Azu
Hey look, I can quote a tenth of your post and say something random in reply to to it for no reason whatsoever, just like you;



sinsi wrote:
a
pizza








Wow, what an interesting way to move along a discussion! Not. Rolling Eyes





Hmm.. actually, come to think of it, all of your posts in this thread were rather random/nonsensical.

_________________
Post 16 Nov 2009, 11:13
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 693
Location: Adelaide
sinsi
Azu wrote:
f0dder wrote:
Azu wrote:
DOS386 wrote:
Code:
call @f 
@@: 
pop [pointer]
    


BTW, the "code" is strange, first, I personally completely avoid pointer's in FASM code, second, to get it "working" at all, you would have to define your "pointer" as "ebp-8" or some other ESP or EBP (or other reg) based thing Wink


Whatever. Write your code in org 0, pop into eax instead, and loop through adding eax to each label. What's the big deal?
...and what's the big deal with using an industry standard OS-supplied
Do you know what an oxymoron is?

OS-specific non-portable code is the exact opposite of standardized.

f0dder wrote:
method of doing this, that handle code as well as data fixups, don't (necessarily - don't know about windows' implementation) cause pages to be flagged as dirty, and don't take up an x86 register for delta-position?
Huh? Who said anything about taking up a register (besides you)?


sinsi wrote:
call @f
@@:
pop [pointer]

Then what?
mov eax, [pointer]
add eax,globalvar1+[pointer]-pointer-globalvar
mov eax,[eax]
???



sinsi wrote:
What about
call [GetCurrentProcess]

For windows (at least) global vars are at a fixed address, so we need to do a lot of maths to get its final address using [pointer].
They even used it for MZ exes ffs

Screw that!
Put the address in there at startup and call it directly. Why do people like this indirect call shit so much??? Sad


"...and what's the big deal with using an industry standard OS-supplied"
"...and what's the big deal with using an industry standard OS-supplied method of doing this, that handle code as well as data fixups" etc.

Selective quoting works both ways, troll
Post 16 Nov 2009, 11:24
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1160
Azu
sinsi wrote:
Selective quoting works both ways
Um.. ya, I just taught you that, duh? You did it to me out of the blue for no reason, so I did it back to you.


sinsi wrote:
troll
You're the one trolling. And if you're trying to imply I did it in that post.. did you even look at it? I quoted the entire posts, and responded to them point by point. What you did was quote one random tenth of mine and say something completely random to it for it no reason other than attempting to irritate me/boost your point count.

_________________
Post 16 Nov 2009, 11:31
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
Azu: you need to use a register to address global variables with PIC. And your code is flawed anyway, how are you going to "pop [variable]" when you're running PIC? The standard way is...

"call .delta
.delta: pop REG
sub REG, .delta"

Fixups are industry standard, like it or not. PE isn't the only executable format they'er used in (ELF however seems to favor the delta approach, unless I'm mistaken). And as already mentioned (but ignored in your selective quoting), they handle code as well as data references, and are possible to do without marking pages as dirty. If you do your own manual data-reference fixups, you will be marking pages dirty.

Quote:
OS-specific non-portable code is the exact opposite of standardized.
If you want really portable code, don't write assembly - simple as that :]

Azu wrote:
Why do people like this indirect call shit so much???
Because it's convenient, it's clean, it's flexible, and there's no measurable overhead from it unless you're writing übercrappy code.

Azu wrote:
And when I need to inject my code into another process I use the method I mentioned above, not this bloated OS-specific DLL/fixup crud.
You have a pretty twisted idea of what "bloat" and "os-specific" means.

Azu wrote:
Again, I ask, what is the excuse of all the overhead from virtual memory when address independent code is needed anyways? (whether from this fixup bloat or by doing it yourself like I do)
We've been over this multiple times, so I'll answer with one word: protection.

As an added bonus, fixups are only necessary if
1) you're using ASLR.
2) you're not using ASLR but your prefered load address isn't available.

ASLR is probably beyond your grasp, and you probably haven't heard about picking smart load-addresses for your DLLs either. Ever heard about bound imports?

Azu wrote:
I think it's because this is only needed for injecting code into another process, and if you're doing that you should have no problem fixing the locations yourself.
How many people do code injection on a regular basis? And how many people use it for legitimate purposes?
Post 16 Nov 2009, 12:11
View user's profile Send private message Visit poster's website Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1160
Azu
f0dder wrote:
Azu: you need to use a register to address global variables with PIC. And your code is flawed anyway, how are you going to "pop [variable]" when you're running PIC?
It was pseudo code. =/
And I told you the right way to do it back on page 1.

f0dder wrote:
The standard way is...

"call .delta
.delta: pop REG
sub REG, .delta"

Fixups are industry standard, like it or not. PE isn't the only executable format they'er used in (ELF however seems to favor the delta approach, unless I'm mistaken).
My way would work in an ELF or PE or any other format.

If I make a DLL with fixups will it work in anything other than Windows?

f0dder wrote:
And as already mentioned (but ignored in your selective quoting)
Replying to you point-by-point isn't selective. Selective would be if I did what sinsi did and only quoted a small part of your post and ignored the rest.

f0dder wrote:
, they handle code as well as data references, and are possible to do without marking pages as dirty. If you do your own manual data-reference fixups, you will be marking pages dirty.
Same thing. You just modify the code either way (jmps for "code", movs for "data", whatever).

f0dder wrote:
Quote:
OS-specific non-portable code is the exact opposite of standardized.
If you want really portable code, don't write assembly - simple as that :]
Good luck getting any code compiled in an HLL to run under another OS. It will be relying on OS-specific features like DLL fixups.

f0dder wrote:
Azu wrote:
Why do people like this indirect call shit so much???
Because it's convenient, it's clean, it's flexible, and there's no measurable overhead from it unless you're writing übercrappy code.
What's so unconvenient and unclean about making them direct at startup? You're such a big fan of abstracting stuff to the OS.. so interpret my question as "why doesn't the OS make them direct for you instead of populating import table" if you want.

f0dder wrote:
Azu wrote:
And when I need to inject my code into another process I use the method I mentioned above, not this bloated OS-specific DLL/fixup crud.
You have a pretty twisted idea of what "bloat" and "os-specific" means.
Bloat means extra space used for no reason, OS-specific means it won't run on anything except one single OS...

f0dder wrote:
Azu wrote:
Again, I ask, what is the excuse of all the overhead from virtual memory when address independent code is needed anyways? (whether from this fixup bloat or by doing it yourself like I do)
We've been over this multiple times, so I'll answer with one word: protection.
That's assuming virtual memory and access rights can not be implemented separately.

f0dder wrote:
As an added bonus, fixups are only necessary if
1) you're using ASLR.
Again with hoping the OS will do your work for you.
"ASLR" can be easily implemented in your code and thus work in any OS even ones that don't support doing it for you! Is it really so hard to do such simple things as move around some blocks of code pseudo-randomly that you must require explicit OS support??

f0dder wrote:
2) you're not using ASLR but your prefered load address isn't available.
Because it's running in an environment without virtual memory, or because it's being loaded/injected into another process at runtime.. either way, why not just do it yourself?

f0dder wrote:
ASLR is probably beyond your grasp
LOL? All it is a silly OS implemented "feature" to shuffle your code around if you don't know how to do it yourself.

f0dder wrote:
and you probably haven't heard about picking smart load-addresses for your DLLs either. Ever heard about bound imports?
Have you heard of making your code not depend on getting a certain load-address?

f0dder wrote:
Azu wrote:
I think it's because this is only needed for injecting code into another process, and if you're doing that you should have no problem fixing the locations yourself.
How many people do code injection on a regular basis? And how many people use it for legitimate purposes?
Isn't that what this whole topic is about? Making your program inject code into another process, or a process injecting your code into itself (e.g. loading it as a DLL)? Fixups/address independent code should only be needed for a standalone process if there is no virtual memory.

As for legitimate purposes.. well, explorer.exe on Windows injects several DLLs into itself. Maybe you should delete it. Oh and all the other Windows programs you have, too. Since none of them are legitimate, apparently.

_________________
Post 16 Nov 2009, 12:45
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
Azu wrote:
f0dder wrote:
Azu wrote:
DOS386 wrote:
Code:
call @f 
@@: 
pop [pointer]
    


BTW, the "code" is strange, first, I personally completely avoid pointer's in FASM code, second, to get it "working" at all, you would have to define your "pointer" as "ebp-8" or some other ESP or EBP (or other reg) based thing Wink


Whatever. Write your code in org 0, pop into eax instead, and loop through adding eax to each label. What's the big deal?
...and what's the big deal with using an industry standard OS-supplied
Do you know what an oxymoron is?


NO.

Here you have a working example: http://board.flatassembler.net/topic.php?t=7122
Post 16 Nov 2009, 12:57
View user's profile Send private message Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 693
Location: Adelaide
sinsi
azu wrote:
Isn't that what this whole topic is about? Making your program inject code into another process, or a process injecting your code into itself (e.g. loading it as a DLL)?
ouadji wrote:
hello, Smile
when should we use the directive "fixups" and why ?
I do not understand this directive and I find no clear explanation to this forum topic.
(sorry for my bad english)
Thank you very much.


Yep, I see lots of injection-type stuff there.
Post 16 Nov 2009, 13:06
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1160
Azu
DOS386 wrote:
Azu wrote:
f0dder wrote:
Azu wrote:
DOS386 wrote:
Code:
call @f 
@@: 
pop [pointer]
    


BTW, the "code" is strange, first, I personally completely avoid pointer's in FASM code, second, to get it "working" at all, you would have to define your "pointer" as "ebp-8" or some other ESP or EBP (or other reg) based thing Wink


Whatever. Write your code in org 0, pop into eax instead, and loop through adding eax to each label. What's the big deal?
...and what's the big deal with using an industry standard OS-supplied
Do you know what an oxymoron is?


NO.

Here you have a working example: http://board.flatassembler.net/topic.php?t=7122
lol

Thanks for making another example of actual selective quoting.


sinsi wrote:
azu wrote:
Isn't that what this whole topic is about? Making your program inject code into another process, or a process injecting your code into itself (e.g. loading it as a DLL)?
ouadji wrote:
hello, Smile
when should we use the directive "fixups" and why ?
I do not understand this directive and I find no clear explanation to this forum topic.
(sorry for my bad english)
Thank you very much.


Yep, I see lots of injection-type stuff there.
You would if you read the second post. Fixups are only for when code (such as a DLL) gets injected into another process (at runtime, not statically at compile time), and the programmer was too lazy or stupid to make his code address independent.

Not for stand-alone code.. unless the host OS doesn't provide virtual memory, but you all keep talking about Windows-specific things (even though this topic is posted under Main), so it probably does.

_________________
Post 16 Nov 2009, 13:12
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 693
Location: Adelaide
sinsi
Azu wrote:

You would if you read the second post. Fixups are only for when code (such as a DLL) gets injected into another process (at runtime, not statically at compile time), and the programmer was too lazy or stupid to make his code address independent.

You have NO idea do you? CALL/JMP = relative, so there is always position-independant code. A global variable at 00403000 is fixed and needs some way of being corrected. The loader takes care of that.
You are fixated on this 'injection' thing. Read the COFF spec and look up the commonly known '.reloc' section.

An address is an address, be it virtual or physical. Red herring, troll.
Post 16 Nov 2009, 13:24
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
Azu wrote:
DOS386 wrote:
Azu wrote:
f0dder wrote:
Azu wrote:
Hell_Killer wrote:
DOS386 wrote:
Code:
call @f 
@@: 
pop [pointer]
    


BTW, the "code" is strange, first, I personally completely avoid pointer's in FASM code, second, to get it "working" at all, you would have to define your "pointer" as "ebp-8" or some other ESP or EBP (or other reg) based thing Wink


Whatever. Write your code in org 0, pop into eax instead, and loop through adding eax to each label. What's the big deal?
there is none
...and what's the big deal with using an industry standard OS-supplied
Do you know what an oxymoron is?


NO.

Here you have a working example: http://board.flatassembler.net/topic.php?t=7122
lol

Thanks for making another example of actual selective quoting.


selective = excessive Laughing
Post 16 Nov 2009, 13:41
View user's profile Send private message Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 693
Location: Adelaide
sinsi
heh heh the dose of icy water strikes again

Ooh look, my 'points' are going up. Right then, one letter per post.
Post 16 Nov 2009, 13:51
View user's profile Send private message Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
r22
This "dueling quotes" thread is childish.

If you want to make a meaningful point, make it in true programmer fashion, with a CODE EXAMPLE THAT COMPILES.
(Dare I suggest, it should even have a few comments that convey the meaning of said code example)

I'm positive someone could of wrote one in the time taken to format all these quotes and come up with asinine (or at least repetitive) replies.

DLL with fixups VS ~self readdressing code
Post 16 Nov 2009, 17:01
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
Azu wrote:
My way would work in an ELF or PE or any other format.

If I make a DLL with fixups will it work in anything other than Windows?
Who cares? You'll need separate PE and ELF (and...) binaries anyway if you want multiple OS support.

Azu wrote:
Replying to you point-by-point isn't selective. Selective would be if I did what sinsi did and only quoted a small part of your post and ignored the rest.
You are doing selective quoting - snipping part of a sentence and replying only to that, while ignoring other parts completely.

Azu wrote:
f0dder wrote:
, they handle code as well as data references, and are possible to do without marking pages as dirty. If you do your own manual data-reference fixups, you will be marking pages dirty.
Same thing. You just modify the code either way (jmps for "code", movs for "data", whatever).
JMP and CALL are EIP-relative and don't require fixups, unless you want to replace indirect call/jmp with runtime-fixup relative calls, which would be lame - that wastes up to 4092 bytes of memory if done "your way".

Azu wrote:
Good luck getting any code compiled in an HLL to run under another OS. It will be relying on OS-specific features like DLL fixups.
ELF-style GOT-PIC vs. PE-style fixups is handled 100% transparently by the compiler and linker in the case of a HLL. And if sticking with a framework, I can achieve 100% portability between windows, linux, OS X with very little os-specific code in the source. Try doing that from assembly... or at binary level. But this is deviating pretty damn far from the point, fixups vs. PIC has extremely little to do with portablity.

Azu wrote:
What's so unconvenient and unclean about making them direct at startup? You're such a big fan of abstracting stuff to the OS.. so interpret my question as "why doesn't the OS make them direct for you instead of populating import table" if you want.
Because it's unnecessary, and would require a much bigger fixup table, as well as combining import information with fixup information. More complex code, bigger executables, and no noticable gain. If that isn't bloat...

Azu wrote:
That's assuming virtual memory and access rights can not be implemented separately.
"Access rights" is only one part of security. x86 paging gives us process separation. Process separation Is Good(TM).

Azu wrote:
"ASLR" can be easily implemented in your code and thus work in any OS even ones that don't support doing it for you! Is it really so hard to do such simple things as move around some blocks of code pseudo-randomly that you must require explicit OS support??
Why on earth would you implement this as a per-app feature? Write the code, get it right once, and keep it in one place. You're the one speaking about bloat, yet you advocate coding practices leading to bloat? O_o

Besides, keep in mind that no OS today is written for assembly programmers (you can bitch and whine and say that this is wrong, but it's just matter of fact so deal with it) - it would be "kinda hard" to write ASLR in a HLL, and it fits a lot more naturaly in the realm of the OS anyway.

Azu wrote:
f0dder wrote:
2) you're not using ASLR but your prefered load address isn't available.
Because it's running in an environment without virtual memory, or because it's being loaded/injected into another process at runtime.. either way, why not just do it yourself?
Why do it yourself if the code can be put in one place and avoid per-executable bloat?

Azu wrote:
Have you heard of making your code not depend on getting a certain load-address?
Yes, and I've coded my fair share of PIC code. I honestly don't see the reason to cramp yourself to such a coding style when there's no use for it - it is more work than simply depending on your linker or OS loader to fix up references, and it brings no mentionable advantages for normal code.

Azu wrote:
Isn't that what this whole topic is about? Making your program inject code into another process, or a process injecting your code into itself (e.g. loading it as a DLL)? Fixups/address independent code should only be needed for a standalone process if there is no virtual memory.
I coded a DLL loader for 32bit DOS extended code and LE executables, where virtual memory wasn't available. This used fixups, since it was a lot more convenient than messing with PIC. And how was this topic about code injection, anyway?

Azu wrote:
As for legitimate purposes.. well, explorer.exe on Windows injects several DLLs into itself. Maybe you should delete it. Oh and all the other Windows programs you have, too. Since none of them are legitimate, apparently.
That's not what I would call code injection Smile
Post 16 Nov 2009, 21:13
View user's profile Send private message Visit poster's website Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1160
Azu
sinsi wrote:
Azu wrote:

You would if you read the second post. Fixups are only for when code (such as a DLL) gets injected into another process (at runtime, not statically at compile time), and the programmer was too lazy or stupid to make his code address independent.

You have NO idea do you? CALL/JMP = relative, so there is always position-independant code.
So what if it's relative? If you don't know ahead of time where you code gets loaded relative to the other code in the process, you need a solution if you want to interact with it.

Also, if you want to do a far call (like to switch between 32bit and 64bit mode), the address is absolute. As it is for instructions like mov.

sinsi wrote:
A global variable at 00403000 is fixed and needs some way of being corrected. The loader takes care of that.
You are fixated on this 'injection' thing. Read the COFF spec and look up the commonly known '.reloc' section.
Again, unless the OS has no virtual memory, this isn't needed except when code is being injected into another process (either being loaded as a DLL at startup, or being forced into it remotely to debug it, or some other OS-dependent method).

sinsi wrote:
An address is an address, be it virtual or physical. Red herring, troll.
Without virtual memory you don't know which address your code will be loaded at.

DOS386 wrote:
Azu wrote:
DOS386 wrote:
Azu wrote:
f0dder wrote:
Azu wrote:
Hell_Killer wrote:
DOS386 wrote:
Code:
call @f 
@@: 
pop [pointer]
    


BTW, the "code" is strange, first, I personally completely avoid pointer's in FASM code, second, to get it "working" at all, you would have to define your "pointer" as "ebp-8" or some other ESP or EBP (or other reg) based thing Wink


Whatever. Write your code in org 0, pop into eax instead, and loop through adding eax to each label. What's the big deal?
there is none
...and what's the big deal with using an industry standard OS-supplied
Do you know what an oxymoron is?


NO.

Here you have a working example: http://board.flatassembler.net/topic.php?t=7122
lol

Thanks for making another example of actual selective quoting.


selective = excessive Laughing

Selective = selecting part of someone's post to quote and ignoring the rest.

Replying to it point by point rather than as one big incoherent blog is pretty much the exact opposite.


sinsi wrote:
heh heh the dose of icy water strikes again

Ooh look, my 'points' are going up. Right then, one letter per post.

Yep, right in your face.

r22 wrote:
This "dueling quotes" thread is childish.

If you want to make a meaningful point, make it in true programmer fashion, with a CODE EXAMPLE THAT COMPILES.
(Dare I suggest, it should even have a few comments that convey the meaning of said code example)

I'm positive someone could of wrote one in the time taken to format all these quotes and come up with asinine (or at least repetitive) replies.

DLL with fixups VS ~self readdressing code

I don't feel like posting code for sinsi to use. Sorry. I already explained the basic concept, it shouldn't be too hard to implement it.


f0dder wrote:
Azu wrote:
My way would work in an ELF or PE or any other format.

If I make a DLL with fixups will it work in anything other than Windows?
Who cares? You'll need separate PE and ELF (and...) binaries anyway if you want multiple OS support.
This topic was posted under Main, so I think the solution isn't supposed to be one that only applies to one certain operating system, otherwise it would have been posted under.. say.. Windows.

f0dder wrote:
Azu wrote:
Replying to you point-by-point isn't selective. Selective would be if I did what sinsi did and only quoted a small part of your post and ignored the rest.
You are doing selective quoting - snipping part of a sentence and replying only to that, while ignoring other parts completely.
What part did I ignore? Besides the dirty memory part which is dependent on the OS's implementation.

f0dder wrote:
Azu wrote:
f0dder wrote:
, they handle code as well as data references, and are possible to do without marking pages as dirty. If you do your own manual data-reference fixups, you will be marking pages dirty.
Same thing. You just modify the code either way (jmps for "code", movs for "data", whatever).
JMP and CALL are EIP-relative and don't require fixups, unless you want to replace indirect call/jmp with runtime-fixup relative calls, which would be lame - that wastes up to 4092 bytes of memory if done "your way".
For the injected code to call stuff in the parent process, or vice versa, it doesn't matter that it's relative, since neither of them know how far apart they are, it may as well be absolute.
And where do you get 4092?
You just need an array of whatever addresses need changed and a few bytes of code.

f0dder wrote:
Azu wrote:
Good luck getting any code compiled in an HLL to run under another OS. It will be relying on OS-specific features like DLL fixups.
ELF-style GOT-PIC vs. PE-style fixups is handled 100% transparently by the compiler and linker in the case of a HLL. And if sticking with a framework, I can achieve 100% portability between windows, linux, OS X with very little os-specific code in the source. Try doing that from assembly... or at binary level. But this is deviating pretty damn far from the point, fixups vs. PIC has extremely little to do with portablity.
If you count having to make completely seperate code for each OS as being "OS-independent", your argument holds water. Sadly this isn't the case. With your HLLs you'll need to have it completely recompiled giving totally different code for each OS, and not being able to compile at all for an OS that lacks fixup support.

f0dder wrote:
Azu wrote:
What's so unconvenient and unclean about making them direct at startup? You're such a big fan of abstracting stuff to the OS.. so interpret my question as "why doesn't the OS make them direct for you instead of populating import table" if you want.
Because it's unnecessary, and would require a much bigger fixup table, as well as combining import information with fixup information. More complex code, bigger executables, and no noticable gain. If that isn't bloat...
More complex? I always got the impression that directly jumping to an address was simpler/faster than reading the contents of a remote memory location, waiting until that read is finished, and then jumping to it. Surely out of order processing doesn't work when the CPU doesn't know where to jump to next yet? So it's going to be stalling until it has loaded that memory, and if it's not in cache that's going to be a while.

f0dder wrote:
Azu wrote:
That's assuming virtual memory and access rights can not be implemented separately.
"Access rights" is only one part of security. x86 paging gives us process separation. Process separation Is Good(TM).
Access rights meaning what part of memory something is allowed to access, and in what way(s).

f0dder wrote:
Azu wrote:
"ASLR" can be easily implemented in your code and thus work in any OS even ones that don't support doing it for you! Is it really so hard to do such simple things as move around some blocks of code pseudo-randomly that you must require explicit OS support??
Why on earth would you implement this as a per-app feature? Write the code, get it right once, and keep it in one place. You're the one speaking about bloat, yet you advocate coding practices leading to bloat? O_o
Because then your code will only work on OSs that implement ASLR for you?
Because even among the OSs that implement it, they might implement it in different ways, and you might want your code to work the same on all OSs?
Because the OS implementation of it sucks and your own is better?
Because it only takes a few bytes to move around blocks of code/data/whatever you wanna call it?
Because relying on the OS to do everything for you is as lazy as using an HLL, so if you're going to then why even use a low level language like FASM?

f0dder wrote:
Besides, keep in mind that no OS today is written for assembly programmers (you can bitch and whine and say that this is wrong, but it's just matter of fact so deal with it) - it would be "kinda hard" to write ASLR in a HLL, and it fits a lot more naturaly in the realm of the OS anyway.
Exactly. The OS wasn't made for low level programmers. So if you're a low level programmer don't rely on the code from the OS.

f0dder wrote:
Azu wrote:
f0dder wrote:
2) you're not using ASLR but your prefered load address isn't available.
Because it's running in an environment without virtual memory, or because it's being loaded/injected into another process at runtime.. either way, why not just do it yourself?
Why do it yourself if the code can be put in one place and avoid per-executable bloat?
Okay, screw making any of our own code then, following that logic.
Why bother making a fast ascii to int function when you can just call an OS-specific function like wpsrintf, and make custom versions of your code for every single OS out there, since they all provide different functions?

Why bother making a nice SSE memcpy when you can just call it from Windows' library, making your code "less bloated"?
Laughing

Bloat isn't just about how much code you put in your program, it's about how much code it consists of while it's running! And if you're importing all of those OS-specific libraries at runtime, it's going to have one helluva bloated memory footprint.


f0dder wrote:
Azu wrote:
Have you heard of making your code not depend on getting a certain load-address?
Yes, and I've coded my fair share of PIC code. I honestly don't see the reason to cramp yourself to such a coding style when there's no use for it - it is more work than simply depending on your linker or OS loader to fix up references, and it brings no mentionable advantages for normal code.
What's so cramping about it? I think depending on certain versions of a certain OS and not running on anything else, is far more cramping. Also, I prefer to use my own code rather than the one-size-fits-all that most OSs export for basic things.

f0dder wrote:
Azu wrote:
Isn't that what this whole topic is about? Making your program inject code into another process, or a process injecting your code into itself (e.g. loading it as a DLL)? Fixups/address independent code should only be needed for a standalone process if there is no virtual memory.
I coded a DLL loader for 32bit DOS extended code and LE executables, where virtual memory wasn't available. This used fixups, since it was a lot more convenient than messing with PIC. And how was this topic about code injection, anyway?
Because unless there is no virtual memory (which there is, since you all keep talking about Windows stuff even though this is posted in Main!), the only time fixups or PIC is needed is when code is injected. I already answered this question like 10 times. Getting sick of having to repeat myself for you guys. Here's another Windows-specific example for you since you can't seem to accept that this topic isn't in the Windows forum; when a process injects a DLL into itself, the code in the DLL does not know ahead of time where it will be loaded!

f0dder wrote:
Azu wrote:
As for legitimate purposes.. well, explorer.exe on Windows injects several DLLs into itself. Maybe you should delete it. Oh and all the other Windows programs you have, too. Since none of them are legitimate, apparently.
That's not what I would call code injection Smile
If code being injected into the address space of an already running process isn't code injection, what is? Do you restrict the meaning to only debugging (injecting code into a remote process without it asking for it)?

_________________
Post 16 Nov 2009, 22:07
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
r22
r22 wrote:
This "dueling quotes" thread is childish.

If you want to make a meaningful point, make it in true programmer fashion, with a CODE EXAMPLE THAT COMPILES.
(Dare I suggest, it should even have a few comments that convey the meaning of said code example)

I'm positive someone could of wrote one in the time taken to format all these quotes and come up with asinine (or at least repetitive) replies.

DLL with fixups VS ~self readdressing code

I guess there's no reasoning with you guys ... carry on
Post 16 Nov 2009, 22:17
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
Azu wrote:
This topic was posted under Main, so I think the solution isn't supposed to be one that only applies to one certain operating system, otherwise it would have been posted under.. say.. Windows.
The topic was originally about the "fixups" directive which, unless I'm mistaken, is for FASM's PE formatter... PE isn't technically a Windows-only format, so it's OK for a topic like this to go in main Wink

Azu wrote:
What part did I ignore? Besides the dirty memory part which is dependent on the OS's implementation.
Yes, you ignored dirty pages, which is one of the reasons this scheme was implemented - but you seem pretty hell-bent on being one-sided and calling things lame and bloated without considering their raison d'être. Trying to fend it off by saying "OMG WOULDN'T BE NECESSARY WITHOUT STUPID VIRTUAL MEMORY!11!" is just ignoring Real Life.

Azu wrote:
f0dder wrote:
JMP and CALL are EIP-relative and don't require fixups, unless you want to replace indirect call/jmp with runtime-fixup relative calls, which would be lame - that wastes up to 4092 bytes of memory if done "your way".

And where do you get 4092?
Fixing up a call/jmp/whatever reference in target code modifies 4 bytes for normal 32bit code, but an entire 4kb page is marked dirty - effetively wasting that memory (requiring it to be paged out to disk instead of discard+pagein, and not letting multiple instances of a proecss share that page). Oh, and I've not even considered the additional memory bloat if those four bytes span a page boundary.

Azu wrote:
You just need an array of whatever addresses need changed and a few bytes of code.
In other words, a fixup table or an IAT, and "a few bytes of code" in the OS loader.

Azu wrote:
If you count having to make completely seperate code for each OS as being "OS-independent", your argument holds water. Sadly this isn't the case. With your HLLs you'll need to have it completely recompiled giving totally different code for each OS, and not being able to compile at all for an OS that lacks fixup support.
One piece of source code (with very little, and possibly none at all, specific code per target platform). I'm not interested in binary-code-runs-everywhere since that's a pipe dream considering the plethora of hardware and operating systems around today.

And again, fixups is an implementation detail handled by compiler/linker, you won't see it affecting anything in the source code (except when writing stuff in assembly - and "really" portable assembly code seems like an oxymoron to me anyway).

Azu wrote:

f0dder wrote:

Azu wrote:
What's so unconvenient and unclean about making them direct at startup? You're such a big fan of abstracting stuff to the OS.. so interpret my question as "why doesn't the OS make them direct for you instead of populating import table" if you want.

Because it's unnecessary, and would require a much bigger fixup table, as well as combining import information with fixup information. More complex code, bigger executables, and no noticable gain. If that isn't bloat...
More complex? I always got the impression that directly jumping to an address was simpler/faster than reading the contents of a remote memory location, waiting until that read is finished, and then jumping to it. Surely out of order processing doesn't work when the CPU doesn't know where to jump to next yet? So it's going to be stalling until it has loaded that memory, and if it's not in cache that's going to be a while.
Yes, the x86 code and executable format to handle this is more complex than the very simple PE fixup information (which, btw, is stored in a format that makes it simple and fast to do fixups to a single page - useful when demand-loading or pagein() of a discard page, as opposed to read-full-exe-apply-all-fixups).

You're tring to twist the argument into CPU logic and IATs rather than fixups. The runtime cost of the IAT indirection means zilch, you are not going to be calling an external API function in a time-critical inner loop, otherwise you're a bloody moron who should either think long and hard about restructuring your applications, or give up programming entirely.

Azu wrote:
f0dder wrote:
"Access rights" is only one part of security. x86 paging gives us process separation. Process separation Is Good(TM).

Access rights meaning what part of memory something is allowed to access, and in what way(s).
When talking about computer security, access rights is normally defined at a higher level, such as "does this user has access to that resource based on permissions/ACLs", not lower-level "can this process access that piece of memory" - it helps to share a common vocabulary. How do you propose doing process isolation without x86 paging?

Azu wrote:
Because then your code will only work on OSs that implement ASLR for you?
Code should function transparently whether it's running with ASLR or not - it's an added and optional security barrier, not a requirement.

Azu wrote:
Because even among the OSs that implement it, they might implement it in different ways, and you might want your code to work the same on all OSs?
Again, ASLR should be transparent. You shouldn't depend on "your code to work the same on all OSs", that's generally a pipe dream... and the whole point of ASLR is too add Randomization, anyway.

Azu wrote:
Because the OS implementation of it sucks and your own is better?
Doing it on your own marks all the pages as dirty - which means your implementation will suck.

Azu wrote:
Because it only takes a few bytes to move around blocks of code/data/whatever you wanna call it?
I'd rather have those "few bytes" in the OS instead of per-application bloat Smile

Azu wrote:
Because relying on the OS to do everything for you is as lazy as using an HLL, so if you're going to then why even use a low level language like FASM?
Still haven't found a cure for the NIH syndrome?

Azu wrote:
Okay, screw making any of our own code then, following that logic.
Why bother making a fast ascii to int function when you can just call an OS-specific function like wpsrintf, and make custom versions of your code for every single OS out there, since they all provide different functions?
If I need a generic ascii-to-int function, I use libc or whatever - which is going to be present on any OS I port my code to. If I need something fast, after benchmarks showing that this function is a bottleneck, I'll roll my own as necessary.

Azu wrote:
Why bother making a nice SSE memcpy when you can just call it from Windows' library, making your code "less bloated"? Very Happy
Same point as above - no reason to introduce yet a piece of code to maintain if it's not necessary.

Azu wrote:
Bloat isn't just about how much code you put in your program, it's about how much code it consists of while it's running! And if you're importing all of those OS-specific libraries at runtime, it's going to have one helluva bloated memory footprint.
Less so than including your own duplicate functions, because of processes being able to share (non-dirty!) physical memory pages Smile

Azu wrote:
f0dder wrote:
Yes, and I've coded my fair share of PIC code. I honestly don't see the reason to cramp yourself to such a coding style when there's no use for it - it is more work than simply depending on your linker or OS loader to fix up references, and it brings no mentionable advantages for normal code.
What's so cramping about it? I think depending on certain versions of a certain OS and not running on anything else, is far more cramping. Also, I prefer to use my own code rather than the one-size-fits-all that most OSs export for basic things.

Having to access global memory with PIC is more work than accessing it directly - and you sacrifice an x86 register for the duration where you need access to that memory. Not a super++ big issue, but it's more convenient writing...
Code:
mov eax, codePointerTable
    

than
Code:
call .delta
.delta: pop eax
sub eax, .detal
lea eax, [eax + codePointerTable]
    


Azu wrote:
Because unless there is no virtual memory (which there is, since you all keep talking about Windows stuff even though this is posted in Main!), the only time fixups or PIC is needed is when code is injected.
I think you mean that if there's virtual memory, that's the only time when fixup/PIC is needed. If you don't have virtual memory where you can guarantee each process gets the base address it wants, you need PIC/fixups all the time.

Azu wrote:
Here's another Windows-specific example for you since you can't seem to accept that this topic isn't in the Windows forum; when a process injects a DLL into itself, the code in the DLL does not know ahead of time where it will be loaded!
If you simply mean "loads a DLL", please don't use the word "inject" (using the right vocabulary etc). If you're loading a DLL normally, the Windows loader will try to give the DLL it's prefered base address, in which case fixups aren't even necessary.

If you mean running your own misguided brute-force code to inject a DLL, well, who knows - what's necessary or not depends on how much your code sucks Smile

Azu wrote:
If code being injected into the address space of an already running process isn't code injection, what is? Do you restrict the meaning to only debugging (injecting code into a remote process without it asking for it)?
"Injecting" code into a process implies that it's being done without the process wanting it / knowing about it.

_________________
Image - carpe noctem
Post 16 Nov 2009, 22:53
View user's profile Send private message Visit poster's website Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1160
Azu
f0dder wrote:
Azu wrote:
This topic was posted under Main, so I think the solution isn't supposed to be one that only applies to one certain operating system, otherwise it would have been posted under.. say.. Windows.
The topic was originally about the "fixups" directive which, unless I'm mistaken, is for FASM's PE formatter... PE isn't technically a Windows-only format, so it's OK for a topic like this to go in main Wink
I thought main was for things "not related to any particular operating system." since it says so right there on the front page.
Meaning that instead of talking about a solution for one particular operating system, we should talk about an OS-independent solution. As in, how to do it without help from the OS.

f0dder wrote:
Azu wrote:
What part did I ignore? Besides the dirty memory part which is dependent on the OS's implementation.
Yes, you ignored dirty pages, which is one of the reasons this scheme was implemented - but you seem pretty hell-bent on being one-sided and calling things lame and bloated without considering their raison d'être.
On the contrary, I'm just following the forum guidelines. You seem pretty hell-bent on ignoring that this wasn't posted under Windows, and thus that "well the way it works in Windows is X" is completely irrelevant to the discussion.

f0dder wrote:
Trying to fend it off by saying "OMG WOULDN'T BE NECESSARY WITHOUT STUPID VIRTUAL MEMORY!11!" is just ignoring Real Life.
Fend what off? Your attempt to derail the discussion into something OS-specific when the forum is specifically labeled as "not related to any particular operating system"? You're just ignoring what forum you're posting in. Also, the Internet is not the same as real life, please keep that in mind.

f0dder wrote:
Azu wrote:
f0dder wrote:
JMP and CALL are EIP-relative and don't require fixups, unless you want to replace indirect call/jmp with runtime-fixup relative calls, which would be lame - that wastes up to 4092 bytes of memory if done "your way".

And where do you get 4092?
Fixing up a call/jmp/whatever reference in target code modifies 4 bytes for normal 32bit code, but an entire 4kb page is marked dirty - effetively wasting that memory (requiring it to be paged out to disk instead of discard+pagein, and not letting multiple instances of a proecss share that page). Oh, and I've not even considered the additional memory bloat if those four bytes span a page boundary.
There you go on about stuff related to one particular operating system. Nothing to do with assembly in general.

f0dder wrote:
Azu wrote:
You just need an array of whatever addresses need changed and a few bytes of code.
In other words, a fixup table or an IAT, and "a few bytes of code" in the OS loader.
Or instead of depending on something that only works in one particular operating system, you could simply take my advice and make your code OS-independent.

f0dder wrote:
Azu wrote:
If you count having to make completely seperate code for each OS as being "OS-independent", your argument holds water. Sadly this isn't the case. With your HLLs you'll need to have it completely recompiled giving totally different code for each OS, and not being able to compile at all for an OS that lacks fixup support.
One piece of source code (with very little, and possibly none at all, specific code per target platform). I'm not interested in binary-code-runs-everywhere since that's a pipe dream considering the plethora of hardware and operating systems around today.
I was under the impression that this forum was for "General discussion about flat assembler" meaning not Visual Basic or .NET or whatever HLL, and "not related to any particular operating system." meaning not solutions that are OS-independent. Since that's what it says in the description.

f0dder wrote:
And again, fixups is an implementation detail handled by compiler/linker, you won't see it affecting anything in the source code (except when writing stuff in assembly - and "really" portable assembly code seems like an oxymoron to me anyway).
Linker? I didn't know FASM had a linker.

And obviously not 100% portable.. you still need to call IO functions to do anything.. but for everything else there is simply no excuse to rely on the OS.

f0dder wrote:
Azu wrote:

f0dder wrote:

Azu wrote:
What's so unconvenient and unclean about making them direct at startup? You're such a big fan of abstracting stuff to the OS.. so interpret my question as "why doesn't the OS make them direct for you instead of populating import table" if you want.

Because it's unnecessary, and would require a much bigger fixup table, as well as combining import information with fixup information. More complex code, bigger executables, and no noticable gain. If that isn't bloat...
More complex? I always got the impression that directly jumping to an address was simpler/faster than reading the contents of a remote memory location, waiting until that read is finished, and then jumping to it. Surely out of order processing doesn't work when the CPU doesn't know where to jump to next yet? So it's going to be stalling until it has loaded that memory, and if it's not in cache that's going to be a while.
Yes, the x86 code and executable format to handle this is more complex than the very simple PE fixup information (which, btw, is stored in a format that makes it simple and fast to do fixups to a single page - useful when demand-loading or pagein() of a discard page, as opposed to read-full-exe-apply-all-fixups).
You completely misinterpreted what I said there. I explained why indirect jumps/calls are less efficient than direct ones. Please re-read it slowly this time.

f0dder wrote:
You're tring to twist the argument into CPU logic and IATs rather than fixups. The runtime cost of the IAT indirection means zilch, you are not going to be calling an external API function in a time-critical inner loop, otherwise you're a bloody moron who should either think long and hard about restructuring your applications, or give up programming entirely.
Maybe in certain particular OSs like Windows that have huge overheads this might be the case. But Main is for discussion about FASM in general, not one particular OS.

f0dder wrote:
Azu wrote:
f0dder wrote:
"Access rights" is only one part of security. x86 paging gives us process separation. Process separation Is Good(TM).

Access rights meaning what part of memory something is allowed to access, and in what way(s).
When talking about computer security, access rights is normally defined at a higher level, such as "does this user has access to that resource based on permissions/ACLs", not lower-level "can this process access that piece of memory" - it helps to share a common vocabulary. How do you propose doing process isolation without x86 paging?
You don't have to come up with a solution just to figure out there's a problem that should be worked on.

f0dder wrote:
Azu wrote:
Because then your code will only work on OSs that implement ASLR for you?
Code should function transparently whether it's running with ASLR or not - it's an added and optional security barrier, not a requirement.
And if you implement it yourself, you can be certain this is the case. Where as if you trust one particular OS to do it for you, it could differ significantly, without you knowing until some irreparable problem has been caused by it.

f0dder wrote:
Azu wrote:
Because even among the OSs that implement it, they might implement it in different ways, and you might want your code to work the same on all OSs?
Again, ASLR should be transparent. You shouldn't depend on "your code to work the same on all OSs", that's generally a pipe dream... and the whole point of ASLR is too add Randomization, anyway.
Right. I forgot, it's impossible to implement any kind of randomization in FASM. We must rely on one particular OS to implement it for us.

Oh wait, that's not true at all, sorry.

f0dder wrote:
Azu wrote:
Because the OS implementation of it sucks and your own is better?
Doing it on your own marks all the pages as dirty - which means your implementation will suck.
There you go on about one particular OS again. Your dirty pages or whatever have nothing to do with assembly in general.

f0dder wrote:
Azu wrote:
Because it only takes a few bytes to move around blocks of code/data/whatever you wanna call it?
I'd rather have those "few bytes" in the OS instead of per-application bloat Smile
Except that would be relying on one particular OS's implementation rather than doing it in FASM. And it wouldn't work in any other OS. Only ones that implement ASLR.

f0dder wrote:
Azu wrote:
Because relying on the OS to do everything for you is as lazy as using an HLL, so if you're going to then why even use a low level language like FASM?
Still haven't found a cure for the NIH syndrome?
Try again. I didn't say you had to make all your code yourself from scratch. I see no problem with someone making a library of functions for FASM for everyone to use, as long as it is peer-reviewed first and remains optional.

Why? Because it would be implemented in the code itself, and thus not tied to one OS in particular.

f0dder wrote:
Azu wrote:
Okay, screw making any of our own code then, following that logic.
Why bother making a fast ascii to int function when you can just call an OS-specific function like wpsrintf, and make custom versions of your code for every single OS out there, since they all provide different functions?
If I need a generic ascii-to-int function, I use libc or whatever - which is going to be present on any OS I port my code to. If I need something fast, after benchmarks showing that this function is a bottleneck, I'll roll my own as necessary.
Statically linking against libc and having the functions actually in your code is one thing, but relying on a certain OS to have a working implementation of it is another thing entirely, since it requires that that particular OS supports it.

f0dder wrote:
Azu wrote:
Why bother making a nice SSE memcpy when you can just call it from Windows' library, making your code "less bloated"? Very Happy
Same point as above - no reason to introduce yet a piece of code to maintain if it's not necessary.
It's necessary if the code is to work without relying on "any particular operating system", that much is certain.

f0dder wrote:
Azu wrote:
Bloat isn't just about how much code you put in your program, it's about how much code it consists of while it's running! And if you're importing all of those OS-specific libraries at runtime, it's going to have one helluva bloated memory footprint.
Less so than including your own duplicate functions, because of processes being able to share (non-dirty!) physical memory pages Smile
Maybe there is one particular operating system that works this way, but Main is for OS-independent solutions.

f0dder wrote:
Azu wrote:
f0dder wrote:
Yes, and I've coded my fair share of PIC code. I honestly don't see the reason to cramp yourself to such a coding style when there's no use for it - it is more work than simply depending on your linker or OS loader to fix up references, and it brings no mentionable advantages for normal code.
What's so cramping about it? I think depending on certain versions of a certain OS and not running on anything else, is far more cramping. Also, I prefer to use my own code rather than the one-size-fits-all that most OSs export for basic things.

Having to access global memory with PIC is more work than accessing it directly - and you sacrifice an x86 register for the duration where you need access to that memory. Not a super++ big issue, but it's more convenient writing...
Code:
mov eax, codePointerTable
    

than
Code:
call .delta
.delta: pop eax
sub eax, .detal
lea eax, [eax + codePointerTable]
    
I meant more along the lines of
Code:
org 0
call @f
@@:
pop eax
lea ecx,[eax+addressesToFix]
@@:
add [ecx],eax
add ecx,4
cmp ecx,addressesToFix.End
jne @b    
Running once at startup.
p.s. untested, might have made a typo or two.

f0dder wrote:
Azu wrote:
Because unless there is no virtual memory (which there is, since you all keep talking about Windows stuff even though this is posted in Main!), the only time fixups or PIC is needed is when code is injected.
I think you mean that if there's virtual memory, that's the only time when fixup/PIC is needed. If you don't have virtual memory where you can guarantee each process gets the base address it wants, you need PIC/fixups all the time.
No what I mean is, it's only needed when virtual memory can not be used. Such as when a piece of code gets injected into another process at runtime to some arbitrary address that isn't known ahead of time.

f0dder wrote:
Azu wrote:
Here's another Windows-specific example for you since you can't seem to accept that this topic isn't in the Windows forum; when a process injects a DLL into itself, the code in the DLL does not know ahead of time where it will be loaded!
If you simply mean "loads a DLL", please don't use the word "inject" (using the right vocabulary etc).
You say tohmahtoe, I say tomato.

f0dder wrote:
If you're loading a DLL normally, the Windows loader will try to give the DLL it's prefered base address, in which case fixups aren't even necessary.
Unless that address is taken. In which case your code will crash, or not be loaded. None of this matters of course, since it's completely OS-dependent and this thread was posted under Main.

f0dder wrote:
If you mean running your own misguided brute-force code to inject a DLL, well, who knows - what's necessary or not depends on how much your code sucks Smile
I'm not even sure what you're getting at there. The Windows implementation of Dynamic Link Libraries is definitely specific to a certain operating system in particular though, I'm sure of that much.

f0dder wrote:
Azu wrote:
If code being injected into the address space of an already running process isn't code injection, what is? Do you restrict the meaning to only debugging (injecting code into a remote process without it asking for it)?
"Injecting" code into a process implies that it's being done without the process wanting it / knowing about it.
If it's being done by another process, wouldn't it be called "remotely injecting"?

_________________
Post 16 Nov 2009, 23:32
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
Well, whatever, you're a hopeless case - I'm pulling out from this one Smile
Post 16 Nov 2009, 23:37
View user's profile Send private message Visit poster's website Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1160
Azu
Nice strategy. When someone counters all your points and you can't think of any way around it, just say "whatever you're hopeless HAHAHA!". Very mature of you to be such a good sport.

_________________
Post 16 Nov 2009, 23:41
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2466
Location: Bucharest, Romania
Borsuc
Azu no offense mate, while I agree with doing stuff yourself and independent, in this case you are just wrong. Your method would be much more bloated, require much more memory, and probably much slower (though this I'm not sure).

Are you going to include the entire Windows API in every executable next time? That's what I call bloated... why do it? Wink


BTW the PE format has nothing to do with an OS -- either a loader supports it or not. Even Linux supports it with Wine. It isn't "Windows specific", it is just a 'container' for code and data.

Whether you like it or not, code and data must be in a container, which is a format. Binary, .com, ELF, PE, doesn't matter. And it has nothing to do with the OS -- that is, none of these formats have something SPECIFIC to an OS.
Post 17 Nov 2009, 01:49
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar.

Powered by rwasa.