flat assembler
Message board for the users of flat assembler.
Index
> Windows > Rewriting code on-the-fly within existing code or data |
Author |
|
rain_storm 02 Jun 2011, 19:16
You can do that, You need to define the section so that it has write and execute access...
section ".code" code readable writable executable |
|||
02 Jun 2011, 19:16 |
|
cod3b453 02 Jun 2011, 20:28
On the x86 architecture, if you modify code in the same or adjacent cache line it can be a lot slower. However, modification is a simple as normal data manipulation:
Code: @@: ; ... self_modify: xor edx,edx mul eax ; ... mov dword [self_modify],0x90909090 ; replace code jmp @b |
|||
02 Jun 2011, 20:28 |
|
garystampa 02 Jun 2011, 21:12
I know it's possible with the architecture, I was mostly concerned with how Windows might set up the various privileges on a typical task such that it would page fault if code-space was written or data-space was executed.
I think I finally found something that confirms it in Windows: http://msdn.microsoft.com/en-us/library/ms679350%28v=VS.85%29.aspx Thanks again for the replies, now I've got some work to do... |
|||
02 Jun 2011, 21:12 |
|
ouadji 02 Jun 2011, 23:14
@rain_storm Quote: You can do that, You need to define the section so that it has write and execute access... There is no way to write in code segment. The only way to write into code segment is to use "ds". Any attempt to use cs will trigger a general protection exception. Code: mov [cs: address], xy ;whatever the type of section, this doesn't works. |
|||
02 Jun 2011, 23:14 |
|
garystampa 02 Jun 2011, 23:33
Interesting. I thought I had read that somewhere a billion years ago.
So what do you make of the MDSN link I posted? In particular the text titled "Use in Self- and Cross-Modifying Code" ? Or are you saying that the selector DS needs to be set with the value in the CS selector and then use DS? Won't changing the selector be a problem? Sorry for my ignorance. Last edited by garystampa on 02 Jun 2011, 23:36; edited 2 times in total |
|||
02 Jun 2011, 23:33 |
|
cod3b453 02 Jun 2011, 23:34
Writable is still required for data write access to that section or it will raise an exception.
|
|||
02 Jun 2011, 23:34 |
|
LocoDelAssembly 03 Jun 2011, 00:26
garystampa, since win32/64 applications run in flat memory model, you just use DS (which is not even required to be used explicitly). ES and SS are also OK, but there is no point in using them unless the CPU instruction and/or addressing use them implicitly (like stos which uses ES and mov reg, [esp] which uses SS).
|
|||
03 Jun 2011, 00:26 |
|
garystampa 03 Jun 2011, 01:04
Very interesting, thank you. I can avoid movs, stos, etc. But it sounds like you're saying DS and CS contain the same selector (table ptr) value.
Why is it that programmers aren't accidentally blowing holes in their code with wild pointers in range of their code? For example: mov esi, accidental_ptr_to_code_area mov [esi], 01234abcdh This would overwrite code? |
|||
03 Jun 2011, 01:04 |
|
Alphonso 03 Jun 2011, 01:17
Code: format PE GUI 4.0 entry start include 'win32a.inc' section '.text' code readable executable writable start: invoke MessageBox,0,Mess,Tit,0 mov dword[Mess],' Mo' invoke MessageBox,0,Mess,Tit,0 exit: invoke ExitProcess,0 Mess db 'Unmodified code section.',0 Tit db 'Self Modifying code.',0 section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include 'api/kernel32.inc' include 'api/user32.inc' |
|||
03 Jun 2011, 01:17 |
|
garystampa 03 Jun 2011, 01:20
I just tested it out with an old Borland C 6 Builder I have.
The DS and CS values are different on boot, but I can change DS to equal CS and then put it back - no troubles. But if I read from it, it crashes. I'll assume from Alphonso's elegant example that my CS selector is set to exec only. I really do learn something new everyday. |
|||
03 Jun 2011, 01:20 |
|
LocoDelAssembly 03 Jun 2011, 03:15
Quote:
In general no, since the code sections are typically set to read-only, so, although DS selector allows writing, the page table entry corresponding to the linear address has its own permissions and can still deny write access despite the selector allowed it. In Alphonso's example, such accidents would be possible (but there isn't any), since the code section is writable. All segments (except GS and FS) have a base address of zero and a limit of 2^32-1 (or 2^64-1 for 64-bit programs), but CS is read-only. But again, the last word regarding access permissions is of the pages. Hope I haven't messed up something in my "explanation". |
|||
03 Jun 2011, 03:15 |
|
garystampa 03 Jun 2011, 08:48
I thank everyone for chiming in on this - I now understand how this works. It's interesting how there's always a way around every effort to protect us from ourselves. And thank goodness for that.
|
|||
03 Jun 2011, 08:48 |
|
me239 06 Jun 2011, 07:27
Apparently it's not
Code: executable, code and writable, so we have to OR it with 0x00000020 (code), 0x20000000 ( executable ) and 0x80000000 ( writable ). or dword ptr ds:[esi+24h],0A0000020h Told you VX'ing would come in handy EDIT: May have misunderstood. I thought the question was whether or not you can modify the '.code' section and not CS. |
|||
06 Jun 2011, 07:27 |
|
rain_storm 07 Jun 2011, 15:34
@me239 That was also my initial understanding of the question. But I dont think everyone is talking about the same thing in this thread.
On one side people are complaining that you cannot write to memory using cs. On the other side you have people saying that the problem is the access rights that you give to each section. Two sides arguing valid points about completely different things. @thread No-one uses cs to read / write to memory. Everyone just uses the ds and es selectors because thats what they are there for. Its the Global Descriptor Table and the Local Descriptor Table that have the final say. You can have multiple descriptors each pointing at the exact same location in memory and each with different access rights. One descriptor may allow you to read / write the memory. Another will allow you to read / execute that same memory. By specifying the cs selector you are forcing the CPU to use the entry that describes that memory as read / execute. If you try to write to this memory using cs then it will generate a General Protection Fault. But if you just use ds or any other selector then the CPU will use the descriptor that says the memory is read / write. And there's no problem. http://wiki.osdev.org/GDT_Tutorial http://wiki.osdev.org/GDT |
|||
07 Jun 2011, 15:34 |
|
f0dder 12 Jun 2011, 10:50
garystampa wrote: in order to teach some concepts to some new knuckleheads who think C++ can do things ASM can't... As for self-modifying code, I'd recommend against it - unless you do very infrequent modifications (like choosing optimal codepaths at program start), your code will end up slower on modern CPUs, not to mention you're abolishing memory protection and run the risk of anti-malware apps going apeshit. Instead of setting your PE code sections as writable, you can use VirtualProtect to temporarily have write capability. If you think two kernel calls (protect-off and protect-on) are too expensive, you're modifying the code section too often. Don't try to build executable code on the stack (or heap), newer Windows versions protect against this - and with good reason, since it's one of the major buffer overflow attack vectors. If you do dynamically generated code, stick it in VirtualAlloc'ed buffers. |
|||
12 Jun 2011, 10:50 |
|
garystampa 14 Jun 2011, 12:59
Thanks for your input. Obviously all of the things you stated are true in a PC-centric world.
As I stated at the start - the code is running on 8-bit micros we use in several of our embedded applications. These "knuckleheads" are very PC-centric: they see the world as a PC. My experience has shown when they finally wake up from that funk they'll thoroughly enjoy what true programming is. But it takes some examples - on a PC... |
|||
14 Jun 2011, 12:59 |
|
f0dder 14 Jun 2011, 16:53
Well, there's a big difference between running on a PC and running on a microcontroller - trying to impose constraints (or the lack of ) from one platform on other other is obviously going to be a big cup of fail - goes both ways.
|
|||
14 Jun 2011, 16:53 |
|
garystampa 18 Jun 2011, 23:25
The examples went fine and they are actually understanding more programming at the metal - and its benefits.
I always enjoy seeing high-level programmers suddenly gain an awe and appreciation for assembler. They have left "knucklehead" status and are now officially "indoctrinated". |
|||
18 Jun 2011, 23:25 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.