Console output without cout or printf()

MosaicFuneral 0 Tallied Votes 353 Views Share

"Hello World!" done a little differently.
Is this safe, unlikely; is there a point to all of this crap, nope; why are parts obfuscated, because I felt like it; was it fun, yes.

You'll need the newest version of MinGW to compile, I used options -O2 -Os -s.

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string.h>

typedef int (*fp)();

class Console
{
    private:
            HANDLE hStdIn, hStdOut;

            bool set_stdin();
            bool set_stdout();
    public:
            bool  running;

            void  print(const char *str, int size);
            void  read(char *out, int size);

            Console(): running(true){
                if(!set_stdin() || !set_stdout())
                 running = false; };
            ~Console()
            { asm("pushl %0\n\t"
                  "call _CloseHandle@4\n\t"
                  "pushl %1\n\t"
                  "call _CloseHandle@4\n\t"
                  :: "r"(hStdIn), "r"(hStdOut):); }
};

bool Console::set_stdin()
{
    fp  *pcode; //Why eax? That's just what most funcs ret with.
    char push_code10[6] = { 0xB8, 0xF6, 0xFF, 0xFF, 0xFF, 0xC3 },
         push_code1[6]  = { 0xB8, 0x01, 0x00, 0x00, 0x00, 0xC3 };

    try {
      pcode = new fp [6];
      if(!pcode) throw; }
    catch(...) {
      return(false); }

    memcpy((char*)pcode, (char*)push_code10, 6);

    asm("call %1\n\t"
        "pushl %%eax\n\t"
        "call _GetStdHandle@4\n\t"
        "movl %%eax, %0\n\t"
        : "=r"(hStdIn): "r"(pcode): "%eax" );

    memcpy((char*)pcode, (char*)push_code1, 1);

    asm("call  %1\n\t"
        "pushl %%eax\n\t"
        "pushl %0\n\t"
        "call _SetConsoleMode@8"
        :: "r"(hStdIn), "r"(pcode): "%eax");
    delete [] pcode;
    return(true);
}

bool Console::set_stdout()
{
    fp  *pcode;
    char push_code11[6] = { 0xB8, 0xF5, 0xFF, 0xFF, 0xFF, 0xC3 };

    try {
      pcode = new fp [6];
      if(!pcode) throw; }
    catch(...) {
      return(false); }

    memcpy((char*)pcode, (char*)push_code11, 6);

    asm("call %1\n\t"
        "pushl %%eax\n\t"
        "call _GetStdHandle@4\n\t"
        "movl %%eax, %0": "=r"(hStdOut): "ra"(pcode): "%eax" );
    delete [] pcode;
    return(true);
}

void Console::print(const char *str, int size)
{
    int wrote;
    asm("pushl $0\n\t"
        "pushl %0\n\t"//&wrote
        "pushl %1\n\t"//size
        "pushl %2\n\t"//str
        "pushl %3\n\t"//hStdOut
        "call _WriteConsoleA@20":
        "=rm"(wrote):
        "r"(size),
        "rm"(str),
        "r"(hStdOut):);
    if(wrote != size) running = false;
}

void Console::read(char *out, int size)
{
    DWORD read;
    ReadConsole(hStdIn, out, size, &read, 0);
}

int main()
{
    Console con;
    char   *input;

    if(!con.running) return(1);

    con.print("Hello World!\r\n", 15);
    
    if(!con.running) return(1);

    try {
      input = new char [1];
      if(!input) throw; }
    catch(...) {
      return(1); }

    con.read(input, 1);

    delete [] input;

    return(0);
}
tux4life 2,072 Postaholic

Nice snippet, but the usage of assembler code makes it unportable :) ...

MosaicFuneral 812 Nearly a Posting Virtuoso

Yep, it's: compiler, OS, and machine-arch specific.

Next snippet might related as perhaps a midget-JIT-compiler/runtime-assembler, metamorphic engine or some sort of obfuscator.

jephthah 1,888 Posting Maven

is this C or C++?

i say C-

MosaicFuneral 812 Nearly a Posting Virtuoso

What are you talking about?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.