I have to write Windows program in x86 assembler (I'm using flat assembler) which will be printing contents of predefined memory. I wrote:
format PE console 4.0
include "win32ax.inc"
start:
mov eax, [0x00850095]
cinvoke printf,formatstring, eax
invoke Sleep,-1
formatstring db "%#x"
section '.idata' import data readable
library msvcrt,'msvcrt.dll',\
kernel32,'kernel32.dll'
import msvcrt,printf,'printf'
import kernel32,Sleep,'Sleep'
It's not working :C; can you help me with that?
Your format string is not quite correct. "%#x" should probably be "%08X" if you want to print the value of eax. If you want to print the value located at the address in eax then you need to load the value pointed to by eax and pass that to printf.
The %x format specifier to printf expects an int passed in the varargs, so if you want to print one byte at a time, you need to load a byte, zero-extended, into eax and then pass eax to printf.
Related
Is there a way to make a macro name case insensitive when defining it?
For example,
Consider the input stream: Mov MOV moV mOv
I want the m4 to output to be: mov mov mov mov
The naive way to do this is to define the following m4 macros:
define(Mov,mov)
define(MOV,mov)
define(moV,mov)
define(mOv,mov)
This method becomes tedious when we want to do the same for a 4 or 5 letter word. Is there a better way to do this?
If you want only string transform (want the m4 to output to be) you can use translit:
translit(string, mapfrom, mapto)
Transliterate the characters in the first argument from the
set given by the second argument to the set given by the
third. You cannot use tr(1) style abbreviations.
Your case:
translit(`MoV',`ABCDEFGHIJKLMNOPQRSTUVWXYZ',`abcdefghijklmnopqrstuvwxyz')
Let's create an m4 macro called to_lowercase. Its definition looks as shown below.
define(`to_lowercase',`translit($1,`ABCDEFGHIJKLMNOPQRSTUVWXYZ',`abcdefghijklmnopqrstuvwxyz')')
Now, we can call our macro using to_lowercase(Mov)', to_lowercase(mOV)'.
I'm trying to run a simple code in assembly - I want to save an address to memory.
I'm moving the address into a register and then moving it into the memory, but for some reason the memory isn't updated.
.data
str1: .asciz "atm course number is 234118"
str2: .asciz "234118"
result: .space 8
.text
.global main
main:
xorq %rax, %rax
xorq %rbx, %rbx
leaq str1, %rax
mov %rax, result(,%rbx,1)
ret
What am I doing wrong?
Your debugger is looking at the wrong instance of result. Your code was always fine (although inefficient; use mov %rax, result(%rip) and don't zero an index, or use mov %rax, result(%rbx,,) to use the byte offset as a "base", not "index", which is more efficient).
glibc contains several result symbols, and in GDB info var result shows:
All variables matching regular expression "result":
Non-debugging symbols:
0x000000000040404b result # in your executable, at a normal static address
0x00007ffff7f54f20 result_type
0x00007ffff7f821b8 cached_result
0x00007ffff7f846a0 result # in glibc, at a high address
0x00007ffff7f85260 result # where the dynamic linker puts shared libs
0x00007ffff7f85660 result
0x00007ffff7f86ab8 result
0x00007ffff7f86f48 result
When I do p /x &result to see what address the debugger resolved that symbol to, I get one of the glibc instances, not the instance in your .data section. Specifically, I get 0x7ffff7f85660 as the address, with the content = 0.
When I print the value with a cast to p /x (unsigned long)result, or dump the memory with GDB's x command, I find a 0 there after the store.
(gdb) x /xg &result
0x7ffff7f85660 <result>: 0x0000000000000000
It looks like your system picked a different instance, one that contained a pointer to a libc address or something. I can't copy-paste from your image. These other result variables are probably static int result or whatever inside various .c files in glibc. (And BTW, that looks like a sign of poor coding style; usually you want to return a value instead of set a global or static. But glibc is old and/or maybe there's some justification for some of those.)
Your result: is the asm a compiler would make for static void* result if it didn't get optimized away. Except it would put it in .bss instead of .data because it's zero-initialized.
You're using SASM. I used GDB to get more details on exactly what's going on. Looking at the address of result in SASM's debug pane might have helped. But now that we've identified the problem using GDB, we can change your source to fix it for SASM.
You can use .globl result to make it an externally-visible symbol so it "wins" when the debugger is looking for symbols.
I added that and compiled again with gcc -g -no-pie store.s. It works as expected now, with p /x (unsigned long)result giving 0x404028
I'm trying to write a lidt instruction in inline assembly in gcc with -masm=intel and 32 bits (-m32). So I have defined the following structures:
typedef struct {
uint16_t length;
uint32_t base;
} idt_desc;
static idt_desc desc = {
sizeof(idt)-1,
(uint32_t)(uintptr_t)idt,
};
If I were using nasm, I would be done with lidt [desc]. But I'm using inline assembly and have this inside a function:
asm volatile("lidt %0"::"m"(desc):);
This gives me "Error: unsupported instruction `lidt'". The assembly generated looks like this:
lidt QWORD PTR desc
As far as I know, braces are optional in gas intel syntax. So the problem here is the qword ptr which is not acceptable in lidt instruction as it expects a m16&32 operand. How can I tell gcc to use that? i.e., drop qword ptr and just use desc.
You need pack the idt_desc structure as the compiler will add padding between the 16-bit length and the 32-bit base structure members. Even if the compiler had managed to generate the code for this the structure would have been invalid and LIDT would have almost certainly loaded an incorrect IDT record leading to an eventual crash/triple fault at runtime. It should be:
typedef struct {
uint16_t length;
uint32_t base;
} __attribute__((packed)) idt_desc;
The -masm=intel option seems to have caused the compiler to see the unpacked version of the structure as a padded 8 byte structure and then treated it as a 64-bit QWORD. In 32-bit code an LIDT doesn't take a pointer to a QWORD it takes a pointer to a 48-bit value (aka FWORD in some Intel dialects) which is the source of the error. By packing the structure the compiler is no longer generating QWORD since the packed version is 6 bytes in size.
I was wondering if there was any way that would allow me to specify anything other than eax, ebx, ecx and edx as output operands.
Lets say I want to put the content of r8 in a variable, Is it possible to write something like this :
__asm__ __volatile__ (""
:"=r8"(my_var)
: /* no input */
);
It is not clear why would you need to put contents of a specific register into a variable, given a volatile nature of the most of them.
GNU C only has specific-register constraints for the original 8 registers, like "=S"(rsi). For r8..r15, your only option (to avoid needing a mov instruction inside the asm statement) is a register-asm variable.
register long long my_var __asm__ ("r8");
__asm__ ("" :"=r"(my_var)); // guaranteed that r chooses r8
You may want to use an extra input/output constraint to control where you sample the value of r8. (e.g. "+rm"(some_other_var) will make this asm statement part of a data dependency chain in your function, but that will also prevent constant-propagation and other optimizations.) asm volatile may help with controlling the ordering, but that's not guaranteed.
It sometimes works to omit the __asm__ ("" :"=r"(my_var)); statement using the register local as an operand, but it's only guaranteed to work if you do use it: https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables. (And see discussion in comments on a previous version of this answer which suggested you could skip that part.) It doesn't make your code any slower, so don't skip that part to make sure your code is safe in general.
The only supported use for this feature is to specify registers for input and output operands when calling Extended asm (see Extended Asm). This may be necessary if the constraints for a particular machine don’t provide sufficient control to select the desired register. To force an operand into a register, create a local variable and specify the register name after the variable’s declaration. Then use the local variable for the asm operand and specify any constraint letter that matches the register
P.S. This is a GCC extension that may not be portable, but should be available on all compilers that support GNU C inline asm syntax.
gcc doesn't have specific-register constraints at all for some architectures, like ARM, so this technique is the only way for rare cases where you want to force specific registers for input or output operands.
Example:
int get_r8d(void) {
register long long my_var __asm__ ("r8");
__asm__ ("" :"=r"(my_var)); // guaranteed that r chooses r8
return my_var * 2; // do something interesting with the value
}
compiled with gcc7.3 -O3 on the Godbolt compiler explorer
get_r8d():
lea eax, [r8+r8] # gcc can use it directly without a MOV first
ret
It should be possible, based on the answer here:
https://stackoverflow.com/a/43197401/3569229
#include <stdint.h>
uint64_t getsp( void )
{
uint64_t sp;
asm( "mov %%r8, %0" : "=rm" ( sp ));
return sp;
}
You can find a list of register names here: https://www3.nd.edu/~dthain/courses/cse40243/fall2015/intel-intro.html
So your code above would be changed to:
__asm__ __volatile__ ("mov %%r8, %0"
:"=rm"(my_var)
: /* no input */
);
Consider the following simplified example function:
void foo(void) {
int t;
asm("push %0\n\t"
"push %0\n\t"
"call bar"
:
: "m" (t)
:
);
}
If I compile it with Cygwin x86 gcc 4.8.3 without optimization, the push instructions become:
push -4(%ebp)
push -4(%ebp)
This is good. The problem happens with -O:
push 12(%esp)
push 12(%esp)
This is clearly wrong. The first push changes esp, and the second push then accesses the wrong location. I have read that adding "%esp" to the clobber list should fix it, but it does not help. How can I make GCC use a frame pointer or properly consider esp changes?
(Assume that returning from the bar function will set esp to the value it had before the asm statement. I just need to call a thiscall function and am using inline assembly for that.)
I can simply use __attribute__((optimize("-fno-omit-frame-pointer"))) to prevent the problem-causing optimization in this one function. This might be the best solution. – dreamlayers