• Welcome to Valhalla Legends Archive.
 

Does visual c++ 2k3's inline asm support this?

Started by warz, May 01, 2006, 10:25 AM

Previous topic - Next topic

warz

Because it's confusing to me right now, I'd rather just do this in inline asm if it's possible. I'm needing to declare a 5 byte variable (arrayed db?). So can you do this in inline asm?


void func() {
   __asm {
          my_var db 5 dup(?)
          ....
        }
}


and use that variable in the following code? I'm just not sure what the C equiv of that would be.

MyndFyre

QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

Yoni

I think you can use a label and "emit". like something like

__asm {
  my_var:
    __asm emit 0x00
    __asm emit 0x00
    __asm emit 0x00
    __asm emit 0x00
    __asm emit 0x00
}


if you don't care about its physical location inside your assembly, just declare it as a C char[] outside the __asm block.

warz

Ah, well, I've been workin on this WriteMem function, and I'm getting an error saying "illegal operand type" on the two lines I have pointed out below...


void __fastcall WriteMem(DWORD AddressToPatch, DWORD AddressToUse, DWORD PaddingSize) {
    PaddingSize = PaddingSize == NULL ? 0 : PaddingSize;

DWORD OldProtect;
    VirtualProtect((LPVOID)AddressToPatch, 5 + PaddingSize, PAGE_EXECUTE_READWRITE, &OldProtect);

BYTE  CallOperand = 0xE8;
DWORD DataBuffer   = (AddressToUse - (AddressToPatch + 5));
    __asm {
        MOV BYTE PTR AddressToPatch, CallOperand   <-- improper operand type?
        MOV AddressToPatch+1, DataBuffer                 <-- improper operand type?
    }

    for (DWORD x = PaddingSize; x > 0; x--) {
        __asm {
            MOV BYTE PTR [AddressToPatch+1+x], 90h
        }
    }
    VirtualProtect((LPVOID)AddressToPatch, 5 + PaddingSize, OldProtect, &OldProtect);
}


How's this an improper operand type?

Kp

Why not just do:
*(uint8_t*)AddressToPatch = 0xe8;
*(uint32_t*)AddressToPatch = DataBuffer;
memset(reinterpret_cast<uint8_t*>(AddressToPatch) + 5, 0x90, PaddingSize);
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

warz

#5
because ive been told that that extra call to memset is sexually abusing the stack.

Do you know anything about "trampoline" functions, or something? So I can automatically determine the length of the memory address I am going to overwrite, and if its longer - NOP the remaining data, or if its shorter I can repair the overwritten instruction? i guess i know my jmp or call with always be 5 bytes, how can i read the length of the memoryaddress im overwriting?

Kp

Who fed you that line about memset?

Trampolines typically refer to tiny temporary functions created on the stack, and as such should be avoided wherever possible since they're incompatible with NX.  What you want is to disassemble the instruction(s) in the area you're overwriting, so that you can identify their length and thus make appropriate repairs.  Unless you need this to be very general purpose, it's usually cheaper just to look up the lengths by hand in a disassembler and hardcode the results in the program.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

warz

Yeah, that's what I have been doing. Just hardcoding in lengths. Seems to be working fine - was just wondering if there was a way to make this function of mine a little more universal

warz

#8
I guess I'll reply because it's another question.

I'm receiving an error related to my asm, telling me it's detecting a newline? Why? :-(


void DisplayStatInfo(void) {
DWORD offset = Offsets.PrintText;
char *text = "leeeeeeet";

__asm {
    xor edx, edx
           mov ecx, text
           call offset                      <-- new line?
}
}


and my definition of PrinText...


struct MemoryAddresses {
const static DWORD PrintText = 0x004e5d80;
const static DWORD PrintTextPatch = 0x00473b68;
};

MemoryAddresses Offsets;

K

I don't recognize the calling convention you're using (ecx and edx but no eax?), but you could just as easily typedef a function pointer and avoid using assembly like this at all.

something like:


typedef void( __fastcall *pfFoo)(int, int);

unsigned int address = 0xf00;

pfFoo foo = reinterpret_cast<pfFoo>(address);
foo(12, 23);

warz

I guess I don't know much about asm, and calling convetions.

This is just how I see Brood War doing it.

Kp

Brood War uses _fastcall, which is rather inefficient about register usage.  It'd be much better to do it the gcc way, which is: eax, edx, ecx.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

warz

So just about every instruction should use eax, edx and ecx?

UserLoser

Quote from: warz on May 03, 2006, 02:43 AM
So just about every instruction should use eax, edx and ecx?

No :p  Maybe calls to other functions or addresses, probably

warz

#14
Well, this is exactly how brood war calls its print text function


__asm {
          PUSH text
          MOV BYTE PTR DS:[0x6CB51D], 11
          MOV WORD PTR DS:[0x6CB544], CX
          MOV WORD PTR DS:[0x6CB548], 276
          MOV WORD PTR DS:[0x6CB546], DI
          CALL offset
}


It has compiled before, but it now saying it is finding a 'newline' at my call instruction. I don't know why :-(

Edit: Haha, nevermind. 'offset' is a keyword.