I have just started learning assembly, and I am trying to modify a character array.
This is my assembly code:
.data
data byte 'Five', 0
.code
Asm proc
lea rax, data
mov dword ptr[rax], 'Four'
ret
Asm endp
end
And my C++ code:
#include <stdio.h>
#include <conio.h>
// external function
extern "C" char* Asm();
// main function
int main()
{
printf(Asm());
_getch();
}
When I comment out mov dword ptr[rax], 'Four', the result is that the console prints: "Five". But, with the above code uncommented, the result is "ruoF", instead of what I expected it to be, which is obviously "Four".
Why is this happening? How can I get the text to output in the correct direction without having to do some cheap workaround like this: mov dword ptr[rax], 'ruoF'?
You can use:
mov ebx,'Four'
bswap ebx
mov [rax],ebx
Or, on Intel Atom processors that support movbe (can be confirmed with cpuid):
mov ebx,'Four'
movbe [rax],ebx
Related
My problem is related with Assembler and Shellcoding.
I started off by writing my first shellcode and it worked out pretty well so far. I then made an assembly script of the following C code:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int fd = open("test.txt", O_CREAT | O_WRONLY);
write(fd, "Hello World!", 6);
return 0;
}
The assembly code for that piece looks like this:
global _start
_start:
xor eax, eax ; null eax reg
push 0x7478742e ; push "test.txt" on stack
push 0x74736574
mov ebx, esp ; first Argument
mov cl, 0x41 ; Flags O_CREAT | O_WRONLY
mov al, 0x5 ; sys_open
int 0x80
push 0x736b6330 ; "shellcodingr0cks"
push 0x72676e69
push 0x646f636c
push 0x6c656853
mov ebx, eax ; file identifier
mov ecx, esp ; string on the stack
mov dl, 0x10 ; 0x10 is the size of the string
mov al, 0x4 ; sys_write
int 0x80
xor eax, eax ; exit proc
inc eax
int 0x80
The Program works pretty well and I've got the expected output but there is one problem and I don't know why this is occurring.
The filename of the file I'm writing to should be test.txt but it is writing to test.txt^A. I don't know where the ^A is coming from, nor do I know how to fix it.
Does anyone know what is wrong, and how I can fix it?
I need to edit a string received from user in C++ code in assembly. I found this tutorial http://msdn.microsoft.com/en-US/library/y8b57x4b(v=vs.80).aspx and according to it my code should work
int main ()
{
char* s;
s=new char[80];
cin.getline(s,80);
__asm
{
mov eax, offset s
}
}
But the compiler shows an error on the line with mov "improper operand type". What is wrong and how can i fix it?
char* s is a local variable. It will be created when the function is called and "forgotten" when the function returns. There exists no "offset" (i.e an absolute memory address) for it at compiletime. But you can inline-assembler force to load the pointer:
#include <iostream>
using namespace std;
int main ()
{
char* s;
s=new char[80];
__asm
{
mov ebx, s ; = mov ebx, [ebp-4]
mov byte ptr [ebx], 'H'
mov byte ptr [ebx+1], 'e'
mov byte ptr [ebx+2], 'l'
mov byte ptr [ebx+3], 'l'
mov byte ptr [ebx+4], 'o'
mov byte ptr [ebx+5], 0 ; Don't forget the terminator!
}
cout << s << endl;
return 0;
}
So my program is very simple. I have a string "Hello World" and I want to replace 'H' with 'A'. So here is my assembly code for MASM.
char* name = "Hello World";
_asm
{
mov eax, name;
mov ebx, 'A';
mov [eax], ebx;
}
printf("%s", name);
Visual Studio cannot compile this. It alerts me that this program is not working. I suspect my syntax for mov[eax], ebx might be wrong. All comments are appreciated. Thanks!
Here is the image of the alert: https://www.dropbox.com/s/e5ok96pj0mxi6sa/test%20program%20not%20working.PNG
"Hello World" is a literal, i.e a non-writeable constant string. 'name' is a pointer which points to that literal. You can instead define an array, which has to be populated with that literal, i.e. the literal is copied into the array:
#include <stdio.h>
int main (void)
{
char name[] = "Hello World";
_asm
{
lea eax, name; // EAX = address of name
mov ebx, 'A';
mov [eax], bl;
}
printf("%s", name);
return 0;
}
The original code works, if you use the C89-Compiler of MSVC (file-extension .c or command line option /TC), but that does not really meet the standard.
First Character
mov eax, _name; // EAX = address of name
mov bl, 'A';
mov byte[eax], bl;
Second Character
mov eax, _name; // EAX = address of name
mov bl, 'A';
mov byte[eax+1], bl;
MOVS
MOVS - This instruction moves 1 Byte, Word or Doubleword of data from memory location to another.
LODS
LODS - This instruction loads from memory. If the operand is of one byte, it is loaded into the AL register, if the operand is one word, it is loaded into the AX register and a doubleword is loaded into the EAX register.
STOS
STOS - This instruction stores data from register (AL, AX, or EAX) to memory.
CMPS
CMPS - This instruction compares two data items in memory. Data could be of a byte size, word or doubleword.
SCAS
SCAS - This instruction compares the contents of a register (AL, AX or EAX) with the contents of an item in memory.
how in c++ visual can i set labels for when i need to use inline assembly, so it would look like something like this for example...
__asm
{
PUSH EAX
PUSH VAR1
MOV ECX,DWORD PTR DS:[VAR2]
CALL DWORD PTR DS:[VAR3]
JMP VAR4
}
where the VAR varables link to a value or address?
i have tried the following
DWORD VAR2 = 0x991770; //0x991770 is the location of the function
__asm
{
..code
MOV ECX,DWORD PTR DS:[VAR2]
..code
}
but then the app crashes, how is this done?
Use offset variableName to access variables from inline assembly. See reference here.
Example:
char format[] = "%s %s\n";
char hello[] = "Hello";
char world[] = "world";
int main( void )
{
__asm
{
mov eax, offset world
push eax
mov eax, offset hello
push eax
mov eax, offset format
push eax
call printf
//clean up the stack so that main can exit cleanly
//use the unused register ebx to do the cleanup
pop ebx
pop ebx
pop ebx
}
}
C variable names are visible in inline assembly. So if you need data access, just write the var name:
int var2 = 3;
__asm
{
mov ecx, var2
That will compile to the appropriate memory access statement.
For code labels - you just declare them, like in real assembly:
Label1:
mov ecx, 0
jmp Label1
External functions are seen as labels, too. Name mangling applies, though.
If you need the numeric value of the current IP as a general purpose register, there's no direct command, but a very simple workaround is available:
call Next
Next:
pop eax ; eax now is the value of IP at the current point
Oh, and forget about the ds: stuff. You're in Flatland now - check your segment registers at the door.
I have problems with inline assembly in visual c++ 2010 Ultimate (Windows 7 Professional). All my inline assemblies don't work, when I use chars, DWORD strings etc etc... So I copied this code from MSDN in my console application:
// InlineAssembler_Calling_C_Functions_in_Inline_Assembly.cpp
// processor: x86
#include <stdio.h>
char format[] = "%s %s\n";
char hello[] = "Hello";
char world[] = "world";
int main( void )
{
__asm
{
mov eax, offset world
push eax
mov eax, offset hello
push eax
mov eax, offset format
push eax
call printf
//clean up the stack so that main can exit cleanly
//use the unused register ebx to do the cleanup
pop ebx
pop ebx
pop ebx
}
}
I have nothing except those lines in my application, result: The string doesn't get printed and the application crashs. Any ideas why this happens?
Project + Properties, C/C++, Code Generation, select /MTd. Repeat for the Release configuration, select /MT.
If you want to make it work with the non-static version of the CRT then you'll need to write the call like this:
call dword ptr printf
Exports from a DLL need to be called indirectly.
I am assuming that popping into ebx is the reason. It is Your responsibility to maintain the integrity of all registers, excluding eax. Try popping into eax instead.