Reset Register Values ​​in GCC

I need to get the values ​​in registers using GCC.

Something like this:

EAX = 00000002 EBX = 00000001 ECX = 00000005 EDX = BFFC94C0
ESI = 8184C544 EDI = 00000000 EBP = 0063FF78 ESP = 0063FE3C
CF = 0 SF = 0 ZF = 0 OF = 0

Getting 32-bit registers is simple enough, but I'm not sure what the easiest way to get flags is.

In the examples for this book: http://kipirvine.com/asm/

They do this by getting the entire EFLAGS register and moving around for the bit in question. I also thought about this using Jcc and CMOVcc.

Any other suggestions on how to do this? Some test cases for validation will also be useful.

+3
source share
5 answers

.

setjmp. jmp_buf. - Works, , jmp_buf .

setjmp ( ) , .

, :

  • . , , ( try/except ++ ).

  • .

, . , .

, , . .


EFLAGS: :

  PUSHFD
  POP EAX  
  , eax now contains the EFLAG data
+4

64- . 32- , 64- 64 β†’ flag32 ( pushfd pushfq). , CY () OV () ( jc, jnc, jo jno).

#include <stdio.h>
#include <stdint.h>

#define HIGH32(x) ((uint32_t)(((uint64_t)x)>>32))
#define LOW32(x) ((uint32_t)(((uint64_t)x)& 0xFFFFFFFF))

int main(int argc, char** argv)
{
    uint32_t eax32, ebx32, ecx32, edx32;
    uint64_t rax64, rbx64, rcx64, rdx64;

    asm (
         "movl %%eax, %[a1] ;"
         "movl %%ebx, %[b1] ;"
         "movl %%ecx, %[c1] ;"
         "movl %%edx, %[d1] ;"

         "movq %%rax, %[a2] ;"
         "movq %%rbx, %[b2] ;"
         "movq %%rcx, %[c2] ;"
         "movq %%rdx, %[d2] ;"
         :
         [a1] "=m" (eax32), [b1] "=m" (ebx32), [c1] "=m" (ecx32), [d1] "=m" (edx32), 
         [a2] "=m" (rax64), [b2] "=m" (rbx64), [c2] "=m" (rcx64), [d2] "=m" (rdx64)
         );

    printf("eax=%08x\n", eax32);
    printf("ebx=%08x\n", ebx32);
    printf("ecx=%08x\n", ecx32);
    printf("edx=%08x\n", edx32);

    printf("rax=%08x%08x\n", HIGH32(rax64), LOW32(rax64));
    printf("bax=%08x%08x\n", HIGH32(rbx64), LOW32(rbx64));
    printf("cax=%08x%08x\n", HIGH32(rcx64), LOW32(rcx64));
    printf("dax=%08x%08x\n", HIGH32(rdx64), LOW32(rdx64));

    uint64_t flags;

    asm (
         "pushfq        ;"
         "pop %[f1] ;"
         :
         [f1] "=m" (flags)
         );

    printf("flags=%08x%08x", HIGH32(flags), LOW32(flags));

    if(flags & (1 << 0)) // Carry
        printf(" (C1"); 
    else
        printf(" (C0");

    if(flags & (1 << 2)) // Parity
        printf(" P1");
    else
        printf(" P0");

    if(flags & (1 << 4)) // Adjust
        printf(" A1");
    else
        printf(" A0");

    if(flags & (1 << 6)) // Zero
        printf(" Z1");
    else
        printf(" Z0");

    if(flags & (1 << 7)) // Sign
        printf(" S1");
    else
        printf(" S0");

    if(flags & (1 << 11)) // Overflow
        printf(" O1)\n");
    else
        printf(" O0)\n");

    return 0;
}
+1

, Jcc , .

, CMOVcc's:

void dump_regs()
{
  int eax = 0;
  int ebx = 0;
  int ecx = 0;
  int edx = 0;

  int esi = 0;
  int edi = 0;
  int ebp = 0;
  int esp = 0;

  int cf = 0;
  int sf = 0;
  int zf = 0;
  int of = 0;

  int set = 1; // -52(%ebp)

  asm( 
    "movl  %eax, -4(%ebp)\n\t"
    "movl  %ebx, -8(%ebp)\n\t"
    "movl  %ecx, -12(%ebp)\n\t"
    "movl  %edx, -16(%ebp)\n\t"
    "movl  %esi, -20(%ebp)\n\t"
    "movl  %edi, -24(%ebp)\n\t"
    "movl  %ebp, -28(%ebp)\n\t"
    "movl  %esp, -32(%ebp)\n\t"

    "movl  $0, %eax\n\t"
    "cmovb -52(%ebp),%eax\n\t" // mov if CF = 1
    "movl  %eax, -36(%ebp) \n\t" // cf

    "movl  $0, %eax\n\t"
    "cmovs -52(%ebp),%eax\n\t" // mov if SF = 1
    "movl  %eax, -40(%ebp)\n\t" // sf

    "movl  $0, %eax\n\t"
    "cmove -52(%ebp),%eax\n\t" // mov if ZF = 1
    "movl  %eax, -44(%ebp)\n\t" // zf

    "movl  $0, %eax\n\t"
    "cmovo -52(%ebp),%eax\n\t" // mov if OF = 1
    "movl  %eax, -48(%ebp)\n\t" // of

    "movl  -4(%ebp), %eax\n\t" // restore EAX
  );

  printf("EAX = %#08x\tEBX = %#08x\tECX = %#08x\tEDX = %#08x\n",eax,ebx,ecx,edx);
  printf("ESI = %#08x\tEDI = %#08x\tEBP = %#08x\tESP = %#08x\n",esi,edi,ebp,esp);
  printf("CF = %d\tSF = %d\tZF = %d\tOF = %d\n",cf,sf,zf,of);
}

, , - , , , .

0

From the top of my head and correct me if I'm wrong, but you could just allocate some memory, get the address allocated and just write the contents of the register there using the asm bracket ... Or you can just push it onto the stack and like- then read it manually ... I think it will require some good asm code, and this is probably not the perfect way to do something like this, but it will work.

0
source

Source: https://habr.com/ru/post/1699327/


All Articles