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 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 want a code to get the address of a variable using inline assembly with C++.
I'm doing this way, but it takes a value and not the address
#include <stdio.h>
#include <windows.h>
int main()
{
int n = 5;
DWORD addr;
__asm mov ebx, n;
__asm mov addr, ebx;
printf("%x", addr);
return 0;
}
If you really need to do it via assembler, try
__asm lea ebx, n;
__asm mov addr, ebx;
I have this (rather useless) code:
__declspec(noinline)
int foo( char* ptr, int offset )
{
if( 5 / offset == 3 ) {
return 1;
}
if( ptr != ptr + offset ) {
return 2;
}
return 0;
}
int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
if( foo( 0, 0 ) ) {
rand();
}
}
I compile that with optimizations on and get this disassembly:
141: __declspec(noinline)
142: int foo( char* ptr, int offset )
143: {
144: if( 5 / offset == 3 ) {
00401000 push 5
00401002 pop eax
00401003 cdq
00401004 xor ecx,ecx
00401006 idiv eax,ecx
00401008 sub eax,3
0040100B neg eax
0040100D sbb eax,eax
0040100F inc eax
145: return 1;
146: }
147: if( ptr != ptr + offset ) {
148: return 2;
149: }
150: return 0;
151: }
00401010 ret
152:
153: int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
154: {
155: if( foo( 0, 0 ) ) {
00401011 call foo (401000h)
00401016 test eax,eax
00401018 je wmain+0Fh (401020h)
156: rand();
0040101A call dword ptr [__imp__rand (4020A0h)]
157: }
158: }
00401020 xor eax,eax
00401022 ret
The compiler preserved a foo() function call, but compiled foo() by propagating parameters known at compile time into the function body and optimizing the code. It even emitted
warning C4723: potential divide by 0
Is that expected behavior of Visual C++?
I guess so. You told it not to inline the function, but you didn't say it couldn't modify the function based on how it is used. It can see that the function is only ever called as foo(0,0), so why shouldn't it optimize the function for that?
try inserting a call to something like foo(1,2) in addition to the (0,0) call and see what happens.