Robert Spykerman <robert.spykerman@[EMAIL PROTECTED]
> wrote:
> On Apr 11, 11:27 pm, Josh Grams <josh@[EMAIL PROTECTED]
> wrote:
>
> So my understanding is correct. My little dance with the assembler to
> get a blank .text, the code and predefined dict in the .data and
> uninitialized stuff in .bss will actually get linked contiguously - at
> least that's how I interpret the hex dump.
Yup. The .bss section seems to stop a little before the 64 MB mark,
which puzzles me, but isn't terribly important, I guess.
>> The other thing you could do is to put everything in .text, have an
>> empty .data, and then immediately mprotect() everything to rwx. But
>> your way seems fine to me.
>
> Hmm... I'll have to look this syscall up and try it. This method is
> probably more orthodox than my odd way of doing it, isn't it?
>
> OR...
>
> Hmm.. just put assemble the code to the text section instead of data
> as you say, link it and _hack_ the binary - ie assuming the load bits
> for the text segment are at the same location, for the sake of
> illustrating my suggestion, put a 0x07 in byte 0x80 in the header. I
> wonder if that would work.
Yes, exactly. Change byte 0x80 in the file from a 5 to a 7. That's how
I would do it; it probably produces the most "correct" binary. And the
header for the text segment is probably unlikely to move, so you could
write a little program to modify the binary and it might even work on
all Intel OSX boxen.
I *almost* mentioned this last time, but I doubt there's any way to get
the toolchain to do it, and you sounded like you might not be up for
modifying binaries yet. :)
> But as you say this is BSD-ish. Will the assembler or linker still
> expect a .data section I see it allocated 4k to it. I had actually
> expected it to allocate nothing since there was nothing in it - kind
> of hoped the linker would see nothing and not link it in. Oh well.
Er...did you mix up .data and .text there? In the binary I dumped,
there is no .text section. See how the __DATA segment has __data and
__bss sections underneath it, but the __TEXT segment has no section
headers? It's just that the __TEXT segment contains the Mach-o headers,
so it can't be size 0, and sizes go in increments of 4k.
I would think that if you linked with an empty .data section, it would
actually be empty. There would probably be a section header, but other
than that I don't think it should waste any space in the executable...
> DAMN. I gotta learn to read the headers like you.
Heh. Apple's reference has all the structures, and I found the header
file which defines the constants (mach-o/loader.h: appears to be from
cctools). Once you have those it's easy; just a bit tedious.
http://csourcesearch.net/package/cctools-extras/525/cctools-525/include/mach-o/loader.h
> Ok, the executable was not stripped. I actually am not sure what the
> linker put at the end yet.
All the load commands that reference it are for symbols, so it's a
symbol table of some kind. If lina only uses syscalls (which I assume
is true) then it doesn't need to do dynamic linking, so the symbols are
unnecessary and you can just clear the addresses and counts in all the
headers that reference them.
> Thanks for the hex dump. I think I see what you're trying to get at,
> it may not be as complicated as I imagined it'd be.
>
> I don't know what command 4, 5, 6, 8 do. I know I can't kill 7. that
> much I know.
Well, you're not going to "kill" any of the headers. They're embedded
at the start of the text segment, so unless you're prepared to relocate
the whole system down, you're not going to reclaim the space they use.
What you do want to get rid of is the data that some of the headers
reference (which follows the .text/.data sections, so it's in the way of
you saving a bigger system).
4 is a command to load a segment: Apple's docs say "The __LINKEDIT
segment contains raw data used by the dynamic linker, such as symbol,
string, and relocation table entries." 5 and 6 tell the dynamic linker
what the contents of the __LINKEDIT segment are.
8 is a "thread command": "Thread commands contain machine-specific data
structures suitable for use in the thread state primitives." I didn't
look up the details, but I wouldn't touch it. :)
> I'll see what I can come up with after some RTFMing and post some more
> results when I get a chance. Really I see what you want to do is get
> to the '_pagezero' to do the dirty work. Change permissions for it.
> Write what you want. save the binary. I think I am beginning to see
> some ways.
Er... pagezero is a a one-page segment mapped at address zero to make
sure that any attempt at using a null pointer will crash immediately.
It's just error detection.
Here's what I would do: assemble and link the binary (everything in
..text, no .data, uninitialized stuff in .bss), hack it so the text
segment has write permissions (change byte 0x80 from 5 to 7, as you
said).
SAVE-SYSTEM should:
Clear all the offsets and sizes in commands 4, 5, and 6 (so they don't
reference any data). This is the part that I'm not sure is ok, so I'd
try doing it by hand in a hex editor and then make sure the binary still
runs.
Increase the size in command 2 to match your actual size. If you link
with everything in .text, there will be a section header under that
segment command; I'd store the new size there also, though it probably
doesn't matter.
Then just write the whole thing out to a file.
> Thanks for your patience, I am actually beginning to see what you're
> trying to say.
No problem. I know all this stuff that's not actually useful for
anything, so it's fun to find someone who's interested. :)
--Josh


|