News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Outputting Two Values In Console

Started by AgentSmithers, May 18, 2009, 06:28:22 AM

Previous topic - Next topic

AgentSmithers

.486
        .model flat, stdcall
        option casemap :none

          include \masm32\include\windows.inc

          include \masm32\include\user32.inc
          include \masm32\include\kernel32.inc
          include \masm32\include\masm32.inc

          includelib \masm32\lib\user32.lib
          includelib \masm32\lib\kernel32.lib
          includelib \masm32\lib\masm32.lib



                .data
                    Var db 16 dup ("0"); Set 16 Bytes of value "0"

                .data?
                    buffer db ?

                    Number dd ?

                    .code

                    start:

                        lea esi, [offset Var + 15]

                        myloop:
     
                        invoke GetStdHandle, -11
                        invoke WriteConsoleA, eax, esi, 1, ecx, 0 ;Uses 2Byte Tchar's

                        inc byte ptr [esi]

                        invoke StdIn,ADDR buffer, LENGTHOF buffer

                        cmp esi, 123

                        je myout

                        jmp myloop

                        ret

                        myout:

                        invoke StdIn,ADDR buffer, LENGTHOF buffer
                       
                        ret ; You have to Return to Exit Properly or the program will crash!
                       
                    end start



Now I'm aware that WriteConsoleA outputs tchars with are 2byte values... now if you copy and run the code not only is it putting out two values it also inc them which its only sposte to inc one value at a time close to a bruteforce methed.
0
1
2
3
4
5
6
7
8
9
A
B
...


Now this code is doing

0
12
34
56
...

What am I messing up on? =(

And I dont recall WriteConsoleA ever Appending CRLF even looking at the MSDN site for the API? Am I correct?

MichaelW

For the ANSI versions of the functions TCHAR is defined as:

typedef char TCHAR;

For WriteConsole, the fourth parameter is supposed to be the address of a DWORD variable that receives the number of characters written.

Your code is setting ESI to the last byte of Var, is this what you intended?

You code is looping until ESI == 123, but the value of ESI is constant throughout the loop. The statement:

inc byte ptr [esi]

Is incrementing the byte that ESI points to. Furthermore, if ESI is set to address of Var then it is starting out at a value much greater than 123.  A conceptually simple way to create a loop would be something like this:

    mov ebx, 10   ; to loop 10 times
  myloop:
    ; Use the address in ESI and then increment or decrement it.
    dec ebx
    jnz myloop


As long as the stack pointer has the same value it had at program entry, executing a RET will exit the program without problems, but a more "normal" way to do it is the call ExitProcess, as this does not depend on the value of the stack pointer.
eschew obfuscation

AgentSmithers

        .486
        .model flat, stdcall
        option casemap :none

          include \masm32\include\windows.inc

          include \masm32\include\user32.inc
          include \masm32\include\kernel32.inc
          include \masm32\include\masm32.inc

          includelib \masm32\lib\user32.lib
          includelib \masm32\lib\kernel32.lib
          includelib \masm32\lib\masm32.lib



                .data
                    Var db 16 dup ("0"); Set 16 Bytes of value "0"

                .data?
                    STDHandle dd ?

                    buffer db ?

                    Number dd ?

                    .code

                    start:

                        lea esi, [offset Var + 15]

                        invoke GetStdHandle, -11

                        mov STDHandle, eax

                        myloop:

                        inc byte ptr [esi]
     
                        invoke WriteConsoleA, STDHandle, esi, 1, ecx, 0 ;Uses 2Byte Tchar's

                        invoke StdIn,ADDR buffer, LENGTHOF buffer

                        cmp byte ptr [esi], 123

                        je myout

                        jmp myloop

                        ret

                        myout:

                        invoke StdIn,ADDR buffer, LENGTHOF buffer
                       
                        ret ; You have to Return to Exit Properly or the program will crash!
                       
                    end start


Ah fixxed it but its still outpuuting two Char's, Is it due to Var(16) even though its not really assisned in my Program that it is not a Null Char? and if so why dosent it do it the first time around?

redskull

The console will still display your input when you type; so, when the user presses the enter key, that is the CR/LF that appears.  Since pressing the enter key is really TWO entries (a CR and a LF), the stdin has two characters waiting for it; when it comes time to 'pause for any key' a second time, the last part of the enter is still there, and it loops again.  To see this in action, instead of just hitting enter, try typing 'abcdefg (enter)', and you will see both those 9 characters displayed, and 9 digits outputted (because there are 9 characters in the buffer).  To work around this, try the SetConsoleMode() function.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

UtillMasm


AgentSmithers

Ah That makes sence I did type in asdfg and I got mutiple Values back, how do I fix this? Switch stdin to what else?
does masm have a built in pause? ("Press Any Key To Continue")

Thanks!

Neil

There is the inkey macro, which the default text is Press any key to continue.

redskull

Either use GetNumberOfConsoleInputEvents() to figure out how many are waiting in the buffer and then use ReadConsole() to read out exactly that many each time through the loop, or use FlushConsoleInputBuffer() to get rid of any extra each time.
Strange women, lying in ponds, distributing swords, is no basis for a system of government

AgentSmithers

It appears to be a no go, whats wrong with my attempt?

.486
        .model flat, stdcall
        option casemap :none

          include \masm32\include\windows.inc

          include \masm32\include\user32.inc
          include \masm32\include\kernel32.inc
          include \masm32\include\masm32.inc

          includelib \masm32\lib\user32.lib
          includelib \masm32\lib\kernel32.lib
          includelib \masm32\lib\masm32.lib



                .data
                    Var db 16 dup ("0"); Set 16 Bytes of value "0"

                .data?
                    STDHandle dd ?

                    buffer db ?

                    Number dd ?

                    .code

                    start:

                        lea esi, [offset Var + 15]

                        invoke GetStdHandle, -11

                        mov STDHandle, eax

                        myloop:

                        inc byte ptr [esi]
     
                        invoke WriteConsoleA, STDHandle, esi, 1, ecx, 0 ;Uses 2Byte Tchar's

                        invoke StdIn,ADDR buffer, LENGTHOF buffer

                        push offset buffer

                        call FlushConsoleInputBuffer

                        cmp byte ptr [esi], 123

                        je myout

                        jmp myloop

                        ret

                        myout:

                        invoke StdIn,ADDR buffer, LENGTHOF buffer
                       
                        ret ; You have to Return to Exit Properly or the program will crash!
                       
                    end start

redskull

FlushConsoleInputBuffer requres the handle of the buffer, not the address of the holder variable in your program (use another call to GetStdHandle).  Is there any reason you use StdIn instead of the ReadConsole?

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

AgentSmithers

No reason, Ill try Readconsole... Thanks..

Vortex

AgentSmithers,

Why not to use wsprintf + StdOut to write NULL terminated strings?

AgentSmithers

I want this code to be fast a possible but Yes I could do it that way =)

.486
        .model flat, stdcall
        option casemap :none

          include \masm32\include\windows.inc

          include \masm32\include\user32.inc
          include \masm32\include\kernel32.inc
          include \masm32\include\masm32.inc

          includelib \masm32\lib\user32.lib
          includelib \masm32\lib\kernel32.lib
          includelib \masm32\lib\masm32.lib



                .data
                    Var db 16 dup ("0"); Set 16 Bytes of value "0"

                    InputBuffer db 16 dup (0)

                .data?
                    STDHandle dd ?

                    buffer db ?

                    Number dd ?

                    BytesToOutput db ?

                    .code

                    start:

                        lea esi, [offset Var + 15]

                        mov BytesToOutput, 1

                        invoke GetStdHandle, -11

                        mov STDHandle, eax

                        myloop:

                        inc byte ptr [esi]

                        invoke SetConsoleCursorPosition, STDHandle, 0
     
                        invoke WriteConsoleA, STDHandle, esi, BytesToOutput, ecx, 0 ;Uses 2Byte Tchar's

                        push 5

                        call Sleep

                        cmp byte ptr [esi], 122

                        je myout

                        jmp myloop

                        myout:

                        cmp esi, [offset Var + 15]

                        je Jumpover

                        cmp byte ptr [esi + 1], 122 ;If zz

                        je IncNextValue

                        inc byte ptr [esi + 1]

                        mov byte ptr [esi], "0"

                        jmp myloop

                        IncNextValue:

                        Jumpover:

                        mov byte ptr [esi], "0"

                        dec esi

                        inc BytesToOutput

                        jmp myloop
                       
                        ret ; You have to Return to Exit Properly or the program will crash!
                       
                    end start

                BackupToStart:

                    ;invoke StdIn,ADDR buffer, LENGTHOF buffer
                   
                    ret ; You have to Return to Exit Properly or the program will crash!

               end BackupToStart

dedndave

let's start with this:
what's the program supposed to do ?

Tedd

Looks like an amateur attempt at a brute-force password cracker, to me ::)
No snowflake in an avalanche feels responsible.