* Re: hello again :D [not found] <20060107110622.65f5623a.amerei@gmail.com> @ 2006-01-07 3:15 ` Ricardo Nabinger Sanchez 2006-01-07 3:17 ` Ricardo Nabinger Sanchez ` (3 subsequent siblings) 4 siblings, 0 replies; 11+ messages in thread From: Ricardo Nabinger Sanchez @ 2006-01-07 3:15 UTC (permalink / raw) To: linux-assembly Quoting Niel A <amerei@gmail.com> Sent on Sat, 7 Jan 2006 11:06:22 +0000 > first, what am i trying to do? i'm trying to replace an instruction with > a nop. IIRC, you can't change anything in .text section while running, as it (AFAIK) will be marked r-xp (read, execute, p I don't know what is). writing to it would then segfault. anyone confirm/disagree? Regards, and happy new year too (Niel and all of you). :) -- Ricardo Nabinger Sanchez GNU/Linux #140696 [http://counter.li.org] Slackware Linux + FreeBSD Left to themselves, things tend to go from bad to worse. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: hello again :D [not found] <20060107110622.65f5623a.amerei@gmail.com> 2006-01-07 3:15 ` hello again :D Ricardo Nabinger Sanchez @ 2006-01-07 3:17 ` Ricardo Nabinger Sanchez 2006-01-07 3:32 ` Frank Kotler ` (2 subsequent siblings) 4 siblings, 0 replies; 11+ messages in thread From: Ricardo Nabinger Sanchez @ 2006-01-07 3:17 UTC (permalink / raw) To: linux-assembly Quoting Niel A <amerei@gmail.com> Sent on Sat, 7 Jan 2006 11:06:22 +0000 > _start: > xor ebx, ebx > mov byte [t1], 0x90 > > t1: > inc ebx ; try to skip this so exit(0) instead of exit(1); also: this translates into a single byte? otherwise you'd need to overwrite whatever bytes this produces. but again, I believe you cannot modify executable pages (at least not in such manner) :) -- Ricardo Nabinger Sanchez GNU/Linux #140696 [http://counter.li.org] Slackware Linux + FreeBSD Left to themselves, things tend to go from bad to worse. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: hello again :D [not found] <20060107110622.65f5623a.amerei@gmail.com> 2006-01-07 3:15 ` hello again :D Ricardo Nabinger Sanchez 2006-01-07 3:17 ` Ricardo Nabinger Sanchez @ 2006-01-07 3:32 ` Frank Kotler 2006-01-07 3:40 ` joy merwin monteiro 2006-01-12 9:52 ` Hendrik Visage 4 siblings, 0 replies; 11+ messages in thread From: Frank Kotler @ 2006-01-07 3:32 UTC (permalink / raw) To: Niel A; +Cc: linux-assembly Niel A wrote: Hi Niel, > section .text Ricardo is correct - the ".text" section isn't writeable. Nasm knows "write" as a possible section property/attribute. A look at the .o file will show ".text" as writeable. But when ld gets ahold of it, ld knows ".text" is supposed to be readonly, and changes it back! So to fool ld: section code write ... seems to do it. Presumably, there's a reason why code pages are RO - be careful with this stuff! Best, Frank ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: hello again :D [not found] <20060107110622.65f5623a.amerei@gmail.com> ` (2 preceding siblings ...) 2006-01-07 3:32 ` Frank Kotler @ 2006-01-07 3:40 ` joy merwin monteiro 2006-01-07 5:00 ` Frank Kotler 2006-01-12 9:52 ` Hendrik Visage 4 siblings, 1 reply; 11+ messages in thread From: joy merwin monteiro @ 2006-01-07 3:40 UTC (permalink / raw) To: Niel A; +Cc: linux-assembly Hi, Yes, you cannot write to code memory, it will be read only. what you could do is write a dummy function, call it and overwrite the return address on the stack, which is in data memory to return to a different place ie, after t1. IIRC, that will be 4(2?) bytes below top of stack in the function, after the frame pointer. mov (sp - 1), bye; ret ; might work ?? opinions ??? regards, Joy > > section .text > global _start > > _start: > xor ebx, ebx > mov byte [t1], 0x90 > > t1: > inc ebx ; try to skip this so exit(0) instead of exit(1); > > bye: > xor eax, eax > inc eax > int 80h > > i figured that since an "inc" is 1 byte, mov byte [t1], 90h will do the trick. if the nop was succesful, the proggie would have returned a zero exit status instead of one. > thanks for your help. > > tidings, > - niel > - > To unsubscribe from this list: send the line "unsubscribe linux-assembly" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- Only time will tell, but are we listening ? :) ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: hello again :D 2006-01-07 3:40 ` joy merwin monteiro @ 2006-01-07 5:00 ` Frank Kotler 2006-01-07 5:26 ` joy merwin monteiro 2006-01-08 5:17 ` Niel A 0 siblings, 2 replies; 11+ messages in thread From: Frank Kotler @ 2006-01-07 5:00 UTC (permalink / raw) To: joy_mm; +Cc: Niel A, linux-assembly joy merwin monteiro wrote: > Hi, > > Yes, you cannot write to code memory, it will be read only. > what you could do is write a dummy function, call it and overwrite > the return address on the stack, which is in data memory to return to > a different place > ie, after t1. > IIRC, that will be 4(2?) bytes below top of stack in the function, > after the frame pointer. > > mov (sp - 1), bye; > ret ; > > might work ?? opinions ??? It'd work better with esp :) If you had a stack frame (push ebp) the return address would be at [esp + 4], I think. Without it, right at [esp]. Haven't tried this, but it sounds like it should work. I've also heard of copying code onto the stack, and modifying and running it there. Hadn't tried this, but I just gave it a shot, and it seems to work. I'm not sure this is good for anything (legitimate). Best, Frank ; self modifying code - on stack global _start section .text _start: nop ; parking place for gdb ; we don't need to save/restore esp here, but do it, ; as if we were going on to do something :) mov ebp, esp ; make some space on stack, align it, and copy some code there sub esp, move_end - move_me and esp, -8 mov edi, esp mov esi, move_me mov ecx, move_end - move_me rep movsb ; modify code on the stack mov dword [esp + target + 1 - move_me], 42 ; ... and call it call esp ; restore esp mov esp, ebp ; exit with ebx set in our modified (?) code mov eax, 1 int 80h move_me: nop ; fiddle and diddle - just nop ; so our target won't be first nop ; too easy! target: mov ebx, 0 ret move_end: ; uncomment for kernels > 2.6.10 !!! ;section .data ;---------------------------- ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: hello again :D 2006-01-07 5:00 ` Frank Kotler @ 2006-01-07 5:26 ` joy merwin monteiro 2006-01-08 5:17 ` Niel A 1 sibling, 0 replies; 11+ messages in thread From: joy merwin monteiro @ 2006-01-07 5:26 UTC (permalink / raw) To: Frank Kotler; +Cc: linux-assembly > It'd work better with esp :) mebbe :D written code for 8086, rusty ..... If you had a stack frame (push ebp) the > return address would be at [esp + 4], I think. Without it, right at > [esp]. Haven't tried this, but it sounds like it should work. > > I've also heard of copying code onto the stack, and modifying and > running it there. Hadn't tried this, but I just gave it a shot, and it > seems to work. x86 has no concept of a code only data only since they share the same physical address space (AFAIR) Von Neumann , Harvard, all that. so works, me thinks.... > > ; self modifying code - on stack <snip> ------------------------ <\snip> /me worships :D Joy -- Only time will tell, but are we listening ? :) ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: hello again :D 2006-01-07 5:00 ` Frank Kotler 2006-01-07 5:26 ` joy merwin monteiro @ 2006-01-08 5:17 ` Niel A 2006-01-08 1:41 ` Frank Kotler 1 sibling, 1 reply; 11+ messages in thread From: Niel A @ 2006-01-08 5:17 UTC (permalink / raw) To: Frank Kotler; +Cc: linux-assembly woah! lots of stuff to digest there! :D and some new weird instructions too! i've got most parts figured out except this line: "and esp, -8" <- this is supposed to be the alignment thingy you mentioned but i really can't see how this works and why there is a need for one. i always see a line similar to this in gcc -S dumps. it took me a while to understand what "mov dword [esp + target + 1 - move_me], 42" does, but i think i got it after trying to literally draw my way into how the stack frame looked liked (pen and paper) at that moment. i don't know what 42 means though. i forgot that the stack grew downwards (hi to low mem) and that esp points to the stack's top :( i tried running the proggie you made but it segfaulted. so for now, i better hit the books again. tidings -niel On Sat, 07 Jan 2006 00:00:36 -0500 Frank Kotler <fbkotler@comcast.net> wrote: > joy merwin monteiro wrote: > > Hi, > > > > Yes, you cannot write to code memory, it will be read only. > > what you could do is write a dummy function, call it and overwrite > > the return address on the stack, which is in data memory to return to > > a different place > > ie, after t1. > > IIRC, that will be 4(2?) bytes below top of stack in the function, > > after the frame pointer. > > > > mov (sp - 1), bye; > > ret ; > > > > might work ?? opinions ??? > > It'd work better with esp :) If you had a stack frame (push ebp) the > return address would be at [esp + 4], I think. Without it, right at > [esp]. Haven't tried this, but it sounds like it should work. > > I've also heard of copying code onto the stack, and modifying and > running it there. Hadn't tried this, but I just gave it a shot, and it > seems to work. > > I'm not sure this is good for anything (legitimate). > > Best, > Frank > > > ; self modifying code - on stack > > global _start > > section .text > _start: > nop ; parking place for gdb > > ; we don't need to save/restore esp here, but do it, > ; as if we were going on to do something :) > mov ebp, esp > > ; make some space on stack, align it, and copy some code there > sub esp, move_end - move_me > and esp, -8 > mov edi, esp > mov esi, move_me > mov ecx, move_end - move_me > rep movsb > > ; modify code on the stack > mov dword [esp + target + 1 - move_me], 42 > > ; ... and call it > call esp > > ; restore esp > mov esp, ebp > > ; exit with ebx set in our modified (?) code > mov eax, 1 > int 80h > > move_me: > nop ; fiddle and diddle - just > nop ; so our target won't be first > nop ; too easy! > target: > mov ebx, 0 > ret > move_end: > > ; uncomment for kernels > 2.6.10 !!! > ;section .data > ;---------------------------- > > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: hello again :D 2006-01-08 5:17 ` Niel A @ 2006-01-08 1:41 ` Frank Kotler [not found] ` <47c1bd210601080024rf8ae88ey4d136c08af3943fd@mail.gmail.com> [not found] ` <20060108132150.0c5ea4b4.amerei@gmail.com> 0 siblings, 2 replies; 11+ messages in thread From: Frank Kotler @ 2006-01-08 1:41 UTC (permalink / raw) To: Niel A; +Cc: linux-assembly Niel A wrote: > woah! lots of stuff to digest there! :D And lots more where it came from. Fortunately, learnin' stuff is fun - 'cause we've got a whole pile of fun ahead of us! > and some new weird instructions too! > i've got most parts figured out except this line: > "and esp, -8" <- this is supposed to be the alignment > thingy you mentioned but i really can't see how > this works and why there is a need for one. > i always see a line similar to this in gcc -S dumps. Well... it was kind of inspired by gcc dumps. Gcc has some strange ideas about how much to subtract from the stack for a given amount of local variables declared - experiment with it if you want to be amused and mystified. The basic idea is that we want to keep the stack aligned at least on a dword boundary, for reasons of speed. Some of the sse? instructions (I haven't learned the "exotic" instructions) require qword (64-bit) alignment - there are versions that will work on unaligned data, but they're slower. So to be "ready" for that, 8 byte alignment is good. We subtract 9 bytes for the code, so alignment after will be beneficial. As for how it works, if you imagine that "-8" (or 0FFFFFFF8h) in binary, all the upper bits are set, and the lowest three are clear. A bitwise "and" of this with esp clears the three lowest bits, and leaves the upper bits just as they were - effectively truncating esp to the next lowest 8-byte boundary. I wrote this to test the effect - less than I would have expected, actually, but you can see the difference. Presumably, the stack was "nicely" aligned when we found it. We deliberately misalign it by some amount defined on Nasm's command line. ; brain-dead demo of the effect of stack (mis)alignment ; ; assemble with "nasm -f elf myprog.asm -DDELTA=?" 0, 1, 2,... ; ld -s -o myprog myprog.o ; run as "time myprog" global _start section .text _start: mov ecx, 10000000h sub esp, byte DELTA top: push eax call dummy pop eax loop top mov eax, 1 int 80h dummy: ret ;--------------- > it took me a while to understand what > "mov dword [esp + target + 1 - move_me], 42" > does, but i think i got it after trying to > literally draw my way into how the stack > frame looked liked (pen and paper) at that moment. Excellent idea! It isn't too easy to grasp, and you *do* want to have a good idea of "what's where" on the stack! > i don't know what 42 means though. "42" is "the answer" to "life, the universe, and everything. Joke from Douglas Adams' "Hitch-hiker's Guide to the Galaxy". (no one knows what the "question" was). When you do "echo $?", it chirps "42". Okay, I'm easily amused! :) > i forgot that the stack grew downwards > (hi to low mem) and that esp points to > the stack's top :( Yup. The "stack top" is at the "bottom", if you look at it that way. "Just like a stack of plates", they say. Okay... if I envision an "anti-gravity plate-stacker" that stacks plates from the ceiling down, I can almost get it. Well, we diagram "trees" with the "root" at the top, too :) > i tried running the proggie you made but it segfaulted. Oh, oh! What kernel? If a newer kernel (since 2.6.10, I think), did you uncomment the "section .data"? You might need to put a dummy byte in the (writeable!) data section. Newer kernels *require* a writeable section, and require it to be last. Gas users never encounter a problem with this - gas gives you a .data section whether you ask for it or not(!). Nasm (and Fasm) users get what we ask for... so we better remember to ask for it! (I keep forgetting it - that code that copies code to the stack should have a "cld" in it, too. Another one I keep forgetting!) Add a ".data" section (Nasm knows that name, and will make it writeable and put it last) in the example above, too! > so for now, i better hit the books again. Well, if you're going to do it *that* way, yeah. :) Best, Frank ^ permalink raw reply [flat|nested] 11+ messages in thread
[parent not found: <47c1bd210601080024rf8ae88ey4d136c08af3943fd@mail.gmail.com>]
* Re: hello again :D [not found] ` <47c1bd210601080024rf8ae88ey4d136c08af3943fd@mail.gmail.com> @ 2006-01-08 14:40 ` Frank Kotler 0 siblings, 0 replies; 11+ messages in thread From: Frank Kotler @ 2006-01-08 14:40 UTC (permalink / raw) To: linux-assembly@vger.kernel.org seasonhu wrote: > I wonder what's the matter with > http://linuxassembly.org. > > I can't visit it. Works for me... right at the moment... try: http://sf.net/projects/asm if you can't get it. Best, Frank ^ permalink raw reply [flat|nested] 11+ messages in thread
[parent not found: <20060108132150.0c5ea4b4.amerei@gmail.com>]
* Re: hello again :D [not found] ` <20060108132150.0c5ea4b4.amerei@gmail.com> @ 2006-01-08 16:19 ` Frank Kotler 0 siblings, 0 replies; 11+ messages in thread From: Frank Kotler @ 2006-01-08 16:19 UTC (permalink / raw) To: Niel A; +Cc: linux-assembly@vger.kernel.org Niel A wrote: > wow! thanks! i think i understand it now a little! actually, i re-read your email a couple of times, then resorted to whipping up something in c before finally seeing some light. > > ----------------------------------------- > sub esp, move_end - move_me > and esp, -8 > ----------------------------------------- > > you allocated space on the stack By subtracting something from esp. > but fall back on the next lowest 8 byte boundary. but that would mean that the stack is now a little short on space for the size of the function that you wanna copy on it right? No, that gives us a little extra! (low 8 bits) Suppose the stack starts at 0xBFFFF780 ...10000000 subtract 9 bytes for our code 0xBFFFF777 ...01110111 (and -8) ...11111000 ------------ and esp, -8 (0xFFFFFFF8) 0xBFFFF770 ...01110000 So we've got a full 16 bytes "reserved". > is this ok? i'm so sorry. *gomen*. still a bit blurry. perhaps i'm just thinking about it so much. I've been known to confuse myself by thinking too much about the fact that the stack "grows down". I can get to thinking that my whole memory is "upside down". It isn't, of course, the stack uses pefectly ordinary memory. The stack *pointer*, esp, moves "downward" (smaller value) when we add something to the stack with a push or call. This is called the "top" of stack... Previous values on the stack remain at the same address (of course), but with respect to esp, they're at a bigger *negative* offset as we add more to the stack. How do we diagram/envision memory? With high numbers at the top, I suppose, and zero at the bottom. This way, the stack "grows down", but the "top of stack" is at the bottom. Another natural way would be 0, 1, 2, 3 with zero at the top. This is the way our source code reads... instructions at the top go into lower memory, and as we read "down" instructions are going into higher addresses. In this orientation, "top of stack" is at the top, but the stack grows "upward"... as it works into lower addresses. No wonder we're confused! I'm not sure that helps... or otherwise. Observing C output may help. Stepping through your code in a debugger might be better. I like ald (available at SourceForge) better than gdb. Actually, I use an older version of ald - reminds me more of DEBUG (how's *that* for faint praise? :) For debugging, use the "-g" switch for Nasm, and *don't* use the "-s" switch to ld. It helps a *lot* if you start off with a "nop" (right after "_start:") - gives gdb someplace to set a breakpoint, so you can step through your code from the beginning. Seems to matter less with ald. Hang in there! Best, Frank ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: hello again :D [not found] <20060107110622.65f5623a.amerei@gmail.com> ` (3 preceding siblings ...) 2006-01-07 3:40 ` joy merwin monteiro @ 2006-01-12 9:52 ` Hendrik Visage 4 siblings, 0 replies; 11+ messages in thread From: Hendrik Visage @ 2006-01-12 9:52 UTC (permalink / raw) To: Niel A; +Cc: linux-assembly On 1/7/06, Niel A <amerei@gmail.com> wrote: > first, what am i trying to do? i'm trying to replace an instruction with a nop. As mentioned by others "caveat emptor" (Buyer beware :) changing stuff in the "text" or "code" segments aren't always guaranteed as it should be static/read-only to prevent malicious code injections etc. etc. (Read stack smashing and all those insecure coding pratices :() Anycase back to the code in question: > _start: > xor ebx, ebx > mov byte [t1], 0x90 > t1: > inc ebx ; try to skip this so exit(0) instead of exit(1); >bye: > xor eax, eax > inc eax > int 80h<snip> > i figured that since an "inc" is 1 byte, mov byte [t1], 90h will do the trick. if the nop was succesful, the proggie would have returned a zero exit status instead of one. Okay, let's assume for one moment that the .text/code segment is writable. In the modern CPUs it would run fine in the debuggers, but without the debugger it'll mostly allways exit(1). Why? It's called the instruction pipeline, prefetch queue etc. :) An old test between the 8086/80186 and the 8088/80188 was to to modify a byte 5 or 6 bytes ahead and check the results. On the 8086/80186 with a 6byte pre-fetch that byte would already be in the queue before the change to the memory location thus the old instruction will get executed. On the 8088/80188, however, with a 4byte prefetch queue, those byte would be changed in RAM/memory by the time the instruction is fetched, thus the new instruction will get executed. This might be exasparated by the newer CPUs that does several instructions per clock tick like the SPARC CPUs. ie. the SuperSPARCs did three instructions (given certain rules) at once, the UltraSPARC version 1 (they are now past 4) can do four instructions (given the rules) to be executed at once. I do recall the Xeons and Athlons also having multiple instructions per clock tick as they also have multiple processing units on board. Thus, if you want to dynamically change code, do it in a function that you'll call after the change as to try and clear the prefetch (and also the predictive branching) queues -- Hendrik Visage ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2006-01-12 9:52 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20060107110622.65f5623a.amerei@gmail.com>
2006-01-07 3:15 ` hello again :D Ricardo Nabinger Sanchez
2006-01-07 3:17 ` Ricardo Nabinger Sanchez
2006-01-07 3:32 ` Frank Kotler
2006-01-07 3:40 ` joy merwin monteiro
2006-01-07 5:00 ` Frank Kotler
2006-01-07 5:26 ` joy merwin monteiro
2006-01-08 5:17 ` Niel A
2006-01-08 1:41 ` Frank Kotler
[not found] ` <47c1bd210601080024rf8ae88ey4d136c08af3943fd@mail.gmail.com>
2006-01-08 14:40 ` Frank Kotler
[not found] ` <20060108132150.0c5ea4b4.amerei@gmail.com>
2006-01-08 16:19 ` Frank Kotler
2006-01-12 9:52 ` Hendrik Visage
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).