I am given a task to transliterate from Cyrillic to Latin using inline MASM.
I've written the following code, which now can process only simple sounds, like 'a', 'b' and so on.
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <clocale>
#include <Windows.h>
using namespace std;
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
char map[33][4] = { "a",
"b"
, "v"
, "g"
, "d"
, "e"
, "z"
, "z"
, "i"
, "i"
, "k"
, "l"
, "m"
, "n"
, "o"
, "p"
, "r"
, "s"
, "t"
, "u"
, "f"
, "h"
, "c"
, "tch"
, "sh"
, "sch"
, ""
, "yy"
, ""
, "ae"
, "yu"
, "ya"
};
char str_out[160];
char str_in[80];
cin.getline(str_in, 80);
_asm
{
lea esi, str_in;
lea edi, str_out;
Process:
lods
cmp al, '\0';
je End_String;
cmp al, 223;
jb Write_Symbol;
// russian а stands for == 224
translit:
mov ebx, esi;
mov ecx, edi;
xor edi, edi;
lea esi, map;
movzx edi, al;
sub edi, 224
mov al, [esi + edi*4]; // **loads only first character**
mov esi, ebx;
mov edi, ecx;
jmp write_symbol;
Write_Symbol:
stos;
jmp Process;
End_String:
stos;
}
cout << str_out << endl;
system("pause");
return 0;
}
But problem starts when I need to deal with complex sounds like 'tchi', 'cha' , etc.
Basically the task is load a start of corresponding string using esi and edi registers and call system to please print me a string, but I don't understand how to do it, how to load an address of such a string and invoke syscall.
So, thanks to #Peter Cordes, I solved my task :
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <clocale>
#include <Windows.h>
using namespace std;
char map[33][8] = {
"a...",
"b..."
, "v..."
, "g..."
, "d..."
, "e..."
, "z..."
, "z..."
, "i..."
, "i..."
, "k..."
, "l..."
, "m..."
, "n..."
, "o..."
, "p..."
, "r..."
, "s..."
, "t..."
, "u..."
, "f..."
, "h..."
, "c..."
, "tch."
, "sh.."
, "sch."
, "...."
, "yy.."
, "...."
, "ae.."
, "yu.."
, "ya.."
};
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
cout << &map << "\n";
char str_out[160];
char str_in[80];
cin.getline(str_in, 80);
int len = 0;
_asm
{
lea esi, str_in;
lea edi, str_out;
Process:
xor eax, eax;
lodsb
cmp al, '\0';
je End_String;
cmp al, 223;
jb Write_Symbol;
// я == 255
translit:
mov ebx, esi;
mov ecx, edi;
xor edi, edi;
lea esi, map;
movzx edi, al;
sub edi, 224;
mov eax, dword ptr [esi + edi*8];
mov esi, ebx;
mov edi, ecx;
add len, 4;
stosd;
jmp Process;
Write_Symbol:
add len, 1;
stosb;
jmp Process;
End_String:
stosb;
}
str_out[len] = '\0';
for (int i = 0; i < len; i++) {
if (str_out[i] != '.') {
cout << str_out[i];
}
}
cout << "\n";
system("pause");
return 0;
}
I try to use assembler and when I call int 0x80 my program crash. What I should do if I want to output some information in console by assembler in my C++ code?
#include <iostream>
int main()
{
char *msg = "Hello";
__asm
{
mov eax, 4;
mov ebx, 1;
mov ecx, msg;
mov edx, 5;
//int 0x80;
}
system("pause");
return 0;
}
I was found some intresting method to output Hello world in Inline ASM using Visual Studio C++.
char* hi = "Hello World\n";
char* text = "%s";
__asm
{
mov eax, hi; // load C pointer variable from memory
push eax; // function args on the stack with rightmost highest
mov eax, text;
push eax;
call DWORD ptr printf; // indirect call to DLL function
pop eax; // clean up the stack
pop eax; // with these 2 dummy pops
}
More about it is describe in this article: http://rodrigosavage.blogspot.com/2010/07/hello-world-with-inline-asm.html?m=1
I am trying to porting this sample of self-mutation of c to c++, but i am having problems with pointers to make it work this example for c++ OOP. I have changed this the part of displaying the data , but how can I change the rest of pointers?
aa.h
void aa::display(std::string data){
const char* str;
str = data.data();
std::cout << str << std::endl;
}
void aa::printfFunctionStub() {}
void aa::enc(DWORD dwAddress, DWORD dwSize) {
__asm {
mov ecx, dwAddress
add ecx, dwSize
mov eax, dwAddress
C_loop :
xor byte ptr ds : [eax], 0x5A
inc eax
cmp eax, ecx
jl C_loop;
}
}
aa.cpp
class aa{
public:
void debugger();
bool IsVmRunning();
void sandbox();
void foo(void);
void display(std::string data);
void printfFunctionStub();
void enc(DWORD dwAddress, DWORD dwSize);
};
main.cpp
int main(){
DWORD dwPrintFunctionSize = 0, dwOldProtect;
DWORD *fA = NULL, *fB = NULL;
// Obtain the addresses for the functions so we can calculate size.
fA = (DWORD *)&printfFunction;
fB = (DWORD *)&printfFunctionStub;
// Get total function size
dwPrintFunctionSize = (fB - fA);
// Test the function
aa.display("Hello A!\n");
// We need to give ourselves access to modifify data at the given address
VirtualProtect(fA, dwPrintFunctionSize, PAGE_READWRITE, &dwOldProtect);
enc((DWORD)fA, dwPrintFunctionSize); // XOR encrypt the function
enc((DWORD)fA, dwPrintFunctionSize); // XOR decrypt the function
// Restore the old protection
VirtualProtect(fA, dwPrintFunctionSize, dwOldProtect, NULL);
// Test the function
aa.display("Hello B!\n");
_getch();
return 0;
}
I'm trying to compile an inline assembly code which works fine with x86 but as I learned you cannot compile inline assembly code with x64. Is there a work around for this? Any help appreciated. The code segment that I use _asm:
int vfscanf(FILE* file, const char *format, va_list argPtr)
{
size_t count = 0;
const char* p = format;
while(1)
{
char c = *(p++);
if (c == 0)
break;
if (c == '%' && (p[0] != '*' && p[0] != '%'))
++count;
}
if (count <= 0)
return 0;
int result;
_asm
{
mov esi, esp;
}
for (int i = count - 1; i >= 0; --i)
{
_asm
{
mov eax, dword ptr[i];
mov ecx, dword ptr [argPtr];
mov edx, dword ptr [ecx+eax*4];
push edx;
}
}
int stackAdvance = (2 + count) * 4;
_asm
{
mov eax, dword ptr [format];
push eax;
mov eax, dword ptr [file];
push eax;
call dword ptr [fscanf];
mov result, eax;
mov eax, dword ptr[stackAdvance];
add esp, eax;
}
return result;
}
The code segment that I call this function:
int scan(const char * _Format, ... )
{
va_list args;
va_start(args, _Format);
_interlockedbittestandset()
int result = vfscanf(_ptr, _Format, args);
va_end(args);
return result;
}
I was trying to write a wrapper function for all file operations. But I couldn't manage to implement wrapper function for fscanf. My own function is like this:
scan(const char * _Format, ... )
{
va_list args;
va_start(args, _Format);
int result = ::fscanf(_ptr, _Format, args);
va_end(args);
return result;
}
You need to use vfscanf. See more on vfscanf.
int scan(const char * _Format, ... )
{
va_list args;
va_start(args, _Format);
int result = ::vfscanf(_ptr, _Format, args);
va_end(args);
return result;
}
Alternatively to the use to vfscanf which takes a va_list, you may use variadic template:
template <typename ... Ts>
int scan(const char* format, Ts&&... args)
{
int result = ::fscanf(_ptr, format, std::forward<Ts>(args)...);
return result;
}
For the ones who have to use an older standard than C++11 you can implement your own vfscanf function like the following:
int vfscanf(FILE* file, const char *format, va_list argPtr)
{
size_t count = 0;
const char* p = format;
while(1)
{
char c = *(p++);
if (c == 0)
break;
if (c == '%' && (p[0] != '*' && p[0] != '%'))
++count;
}
if (count <= 0)
return 0;
int result;
_asm
{
mov esi, esp;
}
for (int i = count - 1; i >= 0; --i)
{
_asm
{
mov eax, dword ptr[i];
mov ecx, dword ptr [argPtr];
mov edx, dword ptr [ecx+eax*4];
push edx;
}
}
int stackAdvance = (2 + count) * 4;
_asm
{
mov eax, dword ptr [format];
push eax;
mov eax, dword ptr [file];
push eax;
call dword ptr [fscanf];
mov result, eax;
mov eax, dword ptr[stackAdvance];
add esp, eax;
}
return result;
}
For further information.