Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use relative addressing in 64-bit assembler #209

Closed
7x-hex-x7 opened this issue Oct 22, 2021 · 10 comments
Closed

Use relative addressing in 64-bit assembler #209

7x-hex-x7 opened this issue Oct 22, 2021 · 10 comments

Comments

@7x-hex-x7
Copy link

7x-hex-x7 commented Oct 22, 2021

How can I use relative addressing in 64-bit assembler?

I have some code:

            long RIP = 0x13FF60000

            long bTest = RIP + 0x100;

            long pTestValue = RIP + 0x200;

            #region asm_01
            var asm_01 = new Assembler(64);

            //
            asm_01.cmp(__byte_ptr[rax + 0x08], 0x3A);
            asm_01.jne(asm_01.@F);
            asm_01.cmp(__byte_ptr[bTest], 0x01);
            asm_01.jne(asm_01.@F);
            asm_01.mov(ecx, __dword_ptr[pTestValue]);

As a result, it turns out like this:

13FF60000 - 80 78 08 01           - cmp byte ptr [rax+08],3A
13FF60004 - 75 11                 - jne 13FF60017
13FF60006 - 80 3C 25 0001F63F 01  - cmp byte ptr [3FF60100],01
13FF6000E - 75 07                 - jne 13FF60017
13FF60010 - 8B 0C 25 0002F63F     - mov ecx,[3FF60200]

That is, absolute addressing is used here, and the address is "truncated" to 32-bit.

But in another assembler it turns out like this:

13FF60000 - 80 78 08 01           - cmp byte ptr [rax+08],3A
13FF60004 - 75 11                 - jne 13FF60017
13FF60006 - 80 3D F3000000 01     - cmp byte ptr [13FF60100],01
13FF6000D - 90                    - nop 
13FF6000E - 75 07                 - jne 13FF60017
13FF60010 - 8B 0D EA010000        - mov ecx,[13FF60200]
13FF60016 - 90                    - nop 

Can I use relative addressing in Iced? Is it possible to make it so that instead of bytes of the CMP instruction 80 3C 25, bytes 80 3D are used, as in another assembler?

@wtfsck
Copy link
Member

wtfsck commented Oct 22, 2021

What version are you using?

@7x-hex-x7
Copy link
Author

7x-hex-x7 commented Oct 22, 2021

What version are you using?

1.13.0.0 with my little edits according to your answer here #191
I removed (int) in the source code

@wtfsck
Copy link
Member

wtfsck commented Oct 22, 2021

Try the latest version.

@7x-hex-x7
Copy link
Author

7x-hex-x7 commented Oct 22, 2021

Try the latest version.

Now I am getting the error:

System.InvalidOperationException: Operand 0: Displacement must fit in an int : 0x0 cmp byte ptr [13FF60100h],1
   at Iced.Intel.Assembler.Assemble(CodeWriter writer, UInt64 rip, BlockEncoderOptions options) in ...\iced-1.15.0\src\csharp\Intel\Iced\Intel\Assembler\Assembler.cs:line 505
            long RIP = 0x13FF60000

            long bTest = RIP + 0x100;

            long pTestValue = RIP + 0x200;

            #region asm_01
            var asm_01 = new Assembler(64);

            //
            asm_01.cmp(__byte_ptr[rax + 0x08], 0x3A);
            asm_01.jne(asm_01.@F);
            asm_01.cmp(__byte_ptr[bTest], 0x01);
            asm_01.jne(asm_01.@F);
            asm_01.mov(ecx, __dword_ptr[pTestValue]);

@wtfsck
Copy link
Member

wtfsck commented Oct 22, 2021

It's assumed to be an absolute address so that's why you get an error. Those instructions only take a signed 32-bit address and your address doesn't fit in an i32.

The current code uses [rip+xyz] if you try to reference a label but you can't do that here. Shouldn't be difficult to also support this case.

A workaround is to put the address in a 64-bit register first, mov rax,0x123456789ABCDEF0; mov ecx,[rax].

@7x-hex-x7
Copy link
Author

7x-hex-x7 commented Oct 24, 2021

It's assumed to be an absolute address so that's why you get an error. Those instructions only take a signed 32-bit address and your address doesn't fit in an i32.

The current code uses [rip+xyz] if you try to reference a label but you can't do that here. Shouldn't be difficult to also support this case.

A workaround is to put the address in a 64-bit register first, mov rax,0x123456789ABCDEF0; mov ecx,[rax].

So won't be able to make relative addressing in Iсed? :(
Unfortunately the workaround with rax will not work, since I need to do this:
mov [pTest],rbx
that is, this way I will read the value from the register

@wtfsck
Copy link
Member

wtfsck commented Oct 24, 2021

Another workaround, until I add this feature, is to just add it manually like so:

asm.AddInstruction(Instruction.Create(Code.Mov_rm64_r64, new MemoryOperand(Register.RIP, 0x1234_5678_9ABC_DEF0), Register.RBX));

@7x-hex-x7
Copy link
Author

Another workaround, until I add this feature, is to just add it manually like so:

asm.AddInstruction(Instruction.Create(Code.Mov_rm64_r64, new MemoryOperand(Register.RIP, 0x1234_5678_9ABC_DEF0), Register.RBX));

Thank you so much for your help! I found the same way with cmp instruction, everything works fine now:

            asm_01.AddInstruction(Instruction.Create(Code.Cmp_rm8_imm8, new MemoryOperand(Register.RIP, pTest2), 0x01));

Could you add the same feature for cmp instructions in the future? That would be cool

@7x-hex-x7
Copy link
Author

7x-hex-x7 commented Oct 24, 2021

Another workaround, until I add this feature, is to just add it manually like so:

asm.AddInstruction(Instruction.Create(Code.Mov_rm64_r64, new MemoryOperand(Register.RIP, 0x1234_5678_9ABC_DEF0), Register.RBX));

Is it possible to add an opcode Mov_r8_rm64?
Cause it doesnt work with these:
asm_01.mov(al, __byte_ptr[bTest]);
I found a workaround for this with labels:

        long bTest = RIP + 0x24;

        //asm_01
        var asm_01 = new Assembler(64);
        var label_bTest = asm_01.CreateLabel();

        asm_01.mov(al, __byte_ptr[label_bTest]);
        asm_01.mov(__byte_ptr[rbx + 0xD0], al);
        asm_01.jmp((ulong)jmp_01);
        asm_01.nop(8);
        asm_01.Label(ref label_bTest);
        asm_01.add(__[rax], al);

P. S. Found the opcode Mov_r8_rm8, it does the same thing, sorry for the unnecessary trouble

@wtfsck
Copy link
Member

wtfsck commented Oct 24, 2021

Could you add the same feature for cmp instructions in the future? That would be cool

It will work with any instruction that can use a memory operand (and has a modrm byte). #212

I'll close this since it seems everything is working now.

@wtfsck wtfsck closed this as completed Oct 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants