Thread: Enforcing Machine Code Restrictions?

  1. #16
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    matsp: Yes, yes, I know. I was using POP CS as an ideological thing (IIRC I wanted to use that particular instruction when I was playing about with assembler a few months ago and was outraged to find that I couldn't! ).

    I've looked at the RET thing and could feasibly track those as well, although this would start to get to the point where I'd be generating exceptions every few instructions, hmm

    Sebastiani: Aha, but seeing as this is my own executable format, what say I specify that the code pages cannot contain any data? I expect to be able to identify each and every byte as an instruction or part of an instruction and if I can't... well, the code won't be run.

    This avoids the whole halting problem as far as the scanner is concerned. All it needs to know is the size of all instructions.

    I suppose that my idea is effectively a VM with the processing for free (the code itself is already native, but the resources involved aren't).
    Last edited by SMurf; 03-29-2009 at 12:04 PM.

  2. #17
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    It s possible to POP CS, although not specifically with that mnemonic. Simply PUSH the value onto the stack and execute an IRET, although this also pops IP and causes execution to continue at the target address.
    Last edited by abachler; 03-29-2009 at 01:49 PM.

  3. #18
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by abachler View Post
    It s possible to POP CS, although not specifically with that mnemonic. Simply PUSH the value onto the stack and execute an IRET, although this also pops IP and causes execution to continue at the target address.
    You do not need to use IRET (in fact, that would probably not WORK), but a "far ret" would work fine, and "pop" CS. But the point was more that there is no instruction in x86 that restored CS on it's own from the stack (or for that matter "loads" CS from memory, or some such). You have to use one of the JUMP, CALL or RET instructions that take a CS:rIP pair - or use task-switching instructions).

    As to DS and CS being the same, I was referring to x86. Most other processors do not have DS and CS register. Of course, there are at least some processors that have a harvard or pseudo-harvard architecture. A good way to avoid accidentally executing data!

    Note also that my simple push, push, ret example is just ONE of many different ways that we could come up with a "stack-frame that points to a function". You most likely would have to completely follow the whole of the instruciton flow to know what's going on. A more complex example:
    Code:
        mov ebp, esp
        push ebp
        mov eax, 0xFFFFFFFF
        xor  eax, ebp
        not eax
        sub eax, 4
        mov [eax], a
        sub eax, 4
        mov [eax], b
        xchg esp, eax
        ret
    a:
        leave
        ret
    
    ...
    b:
    ...
    [I don't guarantee that the above code is actually CORRECT - but something along those lines WILL be able to execute correctly].

    By the time you can follow such things, you have pretty much build a complete x86 instructin simulator. Which is a MAJOR task.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #19
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    I'm still trying to wrap my head around that one! But you know, it also just goes to show that there really are a lot of paradigms that higher level languages could employ in implementing certain features. You just don't think of that much unless you've worked a lot with assembly, I guess.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #20
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    tbh I've always doubted that I could make this, because if we can just watch a couple instructions to get safe full-speed execution without coming up with our own instruction set, someone would deffo have done it before me. I'm not the sharpest, unfortunately.

    However there only so many instructions that are used for flow control and specifically for changing CS and/or EIP, you could get to a point where you could at least protect against "accidental" bad addresses, even if the system could be defeated in a particular manner.

    This question was effectively me asking myself (referring to you) "why" I am making the VM that I am making when I could to some extents cheat. The answer is that it's the only way to be sure (you can't mess with a VM when the native code only exists at runtime)

  6. #21
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Sure, it comes down to "what are you preventing" - if you are trying to prevent "single diigt age" kids from eating the biscuits, or are you trying to prevent "professional" criminals from robbbing a bank, or professional spies from stealing military secrets.

    The solution to the first is not a solution to the second or third threat (although the other way around probably is!)

    And a common problem in secure computing, by the way - who can you trust, and what can you trust them with.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #22
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Yes, I was refering to the status opins ont eh x86, which cna be used to restrict memory accesses based on teh segment register used for the address. This effectively gives access to increased memory addressability, although afaik it was only used in some industrial computers back in teh 8086 days to extend memory to 4MB and to give multiprocessors access to a shared memory region through the ES register. This of course requires a processors without cache or paging enabled.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Obfuscated Code Contest
    By Stack Overflow in forum Contests Board
    Replies: 51
    Last Post: 01-21-2005, 04:17 PM
  2. Voting Machine Source Code
    By anonytmouse in forum Tech Board
    Replies: 1
    Last Post: 11-03-2003, 05:12 PM
  3. The relationship between C++ and assembly and machine code
    By TotalBeginner in forum C++ Programming
    Replies: 5
    Last Post: 04-22-2002, 02:46 PM
  4. Machine code, asm, poop
    By tim545666 in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 04-02-2002, 01:27 AM
  5. Replies: 4
    Last Post: 01-16-2002, 12:04 AM