Not mine, I just came across it while googling.
Machine instructions are put inside a string literal. Said literal is then casted to a function pointer to be called. Pretty exotic, what do you think?
Not mine, I just came across it while googling.
Machine instructions are put inside a string literal. Said literal is then casted to a function pointer to be called. Pretty exotic, what do you think?
Nice hack, though it won't usually work nowadays because instructions outside code segments will not be run by the operating system. You could also just use a char array as { 0xC3, 0xDD, ... } instead of using a string literal with escape codes.
Also, you're fired ![]()
It might be embedded to the code of the program, making it not complain when you run it...
Since string literals in C are not marked as executable it's much more likely that DEP is simply not enabled for all programs.
I've never personally tested this, but http://msdn.microsoft.com/en-us/library/windows/desktop/aa366553%28v=vs.85%29.aspx indicates that VirtualAlloc or VirtualProtect with the appropriate PAGE_EXECUTE flag should allow it.
It's still horrible though. Even if there are sometimes reasons why you may want to do it, it remains horrible (just imagine trying to debug it!)
yep, I didn't know about LLVM when I wrote mine, and when I encountered it didn't want to have to go through the hassle of converting all my stuff over to work with it.LLVM's JIT engine is pretty much the definitive kick-ass explosion-laden version of this concept :-)
Yeah. I was expecting to have to use those functions when I was goofing with it. The VS 2008 debugger had no problem jumping right into the code though. In disassembled view, ofc. It is pretty horrible though.mhagain, on 15 Mar 2013 - 13:26, said:
I've never personally tested this, but http://msdn.microsoft.com/en-us/library/windows/desktop/aa366553(v=vs.85).aspx indicates that VirtualAlloc or VirtualProtect with the appropriate PAGE_EXECUTE flag should allow it.
It's still horrible though. Even if there are sometimes reasons why you may want to do it, it remains horrible (just imagine trying to debug it!)
IIRC, DEP is not enabled by default for user code with 32-bit apps, so you can generally get around needing it.
Yeah. I was expecting to have to use those functions when I was goofing with it. The VS 2008 debugger had no problem jumping right into the code though. In disassembled view, ofc. It is pretty horrible though.mhagain, on 15 Mar 2013 - 13:26, said:
I've never personally tested this, but http://msdn.microsoft.com/en-us/library/windows/desktop/aa366553(v=vs.85).aspx indicates that VirtualAlloc or VirtualProtect with the appropriate PAGE_EXECUTE flag should allow it.
It's still horrible though. Even if there are sometimes reasons why you may want to do it, it remains horrible (just imagine trying to debug it!)
Is RX even used? I remember that with protected mode you could set a selector to be unreadable and unwritable but executable (meaning you can get the CPU run code off it, but you can't get its instructions to read memory from that area), I'd imagine this is still possible in long mode.
it is basically the same as before just with the addition of an NX/XD bit to disable executing code.Is RX even used? I remember that with protected mode you could set a selector to be unreadable and unwritable but executable (meaning you can get the CPU run code off it, but you can't get its instructions to read memory from that area), I'd imagine this is still possible in long mode.
lol, I was literally thinking about creating a thread about this a few minutes ago: writing assembly code without an inline assembler!!!
I've done this many times, but I've never actually used a string. I always used an dynamically allocated array of bytes defining my assembly code. I've never had to do this for a game (except once when I first started coding for MacOSX and I didn't know what Apple's breakpoint function was called), but I've done this very frequently when working on emulators. Not trying to brag, but some of you might actually recognize my nickname. If you do, then I guess I don't need further explanation. ^_^ It really comes in handy if you're writing a static-rec or dynarec engine (I prefer static rec).
For games, I'd only use it to write my own intrinsics for something like SSE, CPUID or those oddball instructions that aren't recognized by the inline assembler. Of course, this isn't an easy task, you'll have to read the docs on Intel's webpage: http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
WBINVD anyone? ![]()
Oh, and depending on what compiler you're using, debugging it isn't hard! XCode disassembles properly written byte encoded assembly code and steps through it normally. That's just one of the many reasons I absolutely LOVE XCode and MacOSX! ![]()
Shogun
@Shogun: yes, this is also a possible reason to write an assembler.
then you can dynamically assembler whatever, without having to manually invoke the Intel docs and generate the machine code sequences by hand.
also, in the simple case, writing an assembler isn't really hard, in my case most of the "work" was the long/tedious job of transcribing the instruction-listings and similar.
(initially, I wrote it over the course of a few days, but the assembler has expanded a bit since then).
though, yes, I have still used manually-generated machine code in a few places, as for certain uses this is more useful (the assembler isn't entirely free...).
as an example, from my listing:
add
04,ib al,i8
X80/0,ib rm8,i8 aleph
WX83/0,ib rm16,i8 aleph
TX83/0,ib rm32,i8 aleph
X83/0,ib rm64,i8
X02/r r8,rm8 aleph
X00/r rm8,r8 aleph
W05,iw ax,i16
WX81/0,iw rm16,i16 aleph
WX03/r r16,rm16 aleph
WX01/r rm16,r16 aleph
T05,id eax,i32
TX81/0,id rm32,i32 aleph
TX01/r rm32,r32 aleph
TX03/r r32,rm32 aleph
X05,id rax,i32
X81/0,id rm64,i32
X03/r r64,rm64
X01/r rm64,r64
...
inc
W40|r r16 leg
T40|r r32 leg
XFE/0 rm8 aleph
WXFF/0 rm16 aleph
TXFF/0 rm32 aleph
XFF/0 rm64 where 'X' basically means where to put the REX prefix, W/T where to insert the operand-size prefix (when relevant), ...
(other letters have other meanings, like V/S for address-size prefix, H/I/J/K/L for VEX and XOP forms, ...).
likewise: '/r' means "insert ModRM here", ',id' means immediate dword, ...
and the last line is basically for flags, such as to indicate when/where sequences are valid (CPU modes, ...).
'leg', basically means "legacy only", 'long' means long-mode only, and 'aleph' was basically for a past x86 subset.
I had once considered having a verifiable x86 subset sort of like NaCl (but more like the JVM verifier), but this idea didn't really go anywhere.
when the assembler is compiled, a tool basically takes the instruction listings, and converts them into the relevant C source files and headers (basically, it converts them into big prebuilt tables).
This topic has been locked by a moderator. New replies are not allowed.
With your permission, GameDev.net uses analytics cookies to understand how people use the platform. You can accept analytics or continue with necessary cookies only. Learn more