flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
x0r4nd 12 Jun 2013, 15:51
Hello, anyone living in this win-planet?
Perhaps I was disrespectful? or My question is too silly? |
|||
![]() |
|
baldr 12 Jun 2013, 18:48
x0r4nd wrote: Perhaps I was disrespectful? ![]() |
|||
![]() |
|
bitRAKE 12 Jun 2013, 21:32
ReadConsole does not null terminate the input, so escrito often includes erroneous characters. This is compounded by using longer API name and then a shorter one - because the input buffer is still dirty. Some rudimentary filtering on the input is needed to correctly determine API string length.
Following your sequence of testing: You can verify this by halting after ReadConsole, after the second entry of "WinExec". Look at apix buffer. Then see that lstrlen returns a value of 11 for length. We are sometimes unlucky to have code work when it shouldn't - hiding errors. _________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
![]() |
|
x0r4nd 12 Jun 2013, 22:48
BitRAKE Thanks for your reply:
About your opinion I inform you: Following the introduction of APIX via console it is reduced in 1 byte the buffer size through by calls to lstrlen and lstrcpyn I have tried several ways to overcome this problem: Conserving "APIX" in its original size and copying it reduced in 1 byte to another variable, then it is twice compared the name in ESI against original APIX and against reduced APIX . I've also cleaned up the buffer in every way possible form and never get to find WinExec again. I definitely think that this is not the real cause of strange behavior. |
|||
![]() |
|
x0r4nd 12 Jun 2013, 23:01
I have also changed the way of comparing the two strings: as you will see in the posted version use both CompareString and lstrcmp.
By using CompareString can push "-1" instead of the size of the strings and the api find real sizes. Nor how it works. The strange thing is that it never stops working properly lstrcmp "control" against the string in ESI. In a latest version I'm using ordinal numbers and seems to work "a little" better |
|||
![]() |
|
bitRAKE 13 Jun 2013, 03:05
The simplest solution would be to use the number of bytes returned by ReadConsole - it will tell of bytes read. On my system ReadConsole puts 13,10 at end of "WinExec", so a reduction by one byte solves nothing. Furthermore, lstcmp and lstrlen require null strings, and no such formating is guaranteed by your code. The fact that it works sometimes is misleading and anecdotal.
_________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
![]() |
|
typedef 13 Jun 2013, 09:53
Logical errors!
Also Why not implement some sort of "caching". Sofor each API you return you create a simple LONG hash and store it. Padd it with the ordinal of the API so if the hash matches just call it by the ordinal. |
|||
![]() |
|
x0r4nd 13 Jun 2013, 14:46
bitRAKE:
I added the following line after entering APIX by console: "invoke lstrcat APIX,pito" where "pito" is defined as TCHAR 0,0 in Data segment. The behavior remains the same. typedef: As I said in the previous post I'm working on a new version seeking the api by its ordinal number or HINT (from what report depends.exe). So there is no mistake: the API is always find. The logic say that ; By just manually type the name of the api and call GetProcAddress should be able to invoke it. But it took months trying and have not succeed. I do not get it either typing the ordinal number and calling for "atoi". I think that : there are some hidden protection mechanism by Microsoft. For all that I chose to use this system shellcode style |
|||
![]() |
|
AsmGuru62 13 Jun 2013, 15:48
This code may cause undefined behaviour:
Code: ; ; buffer apix is copied into itself. Weird... ; invoke lstrcpyn,apix,apix,eax Please check the 'Remarks' here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647491(v=vs.85).aspx Also, Code: invoke WriteConsole,7,[handy],4,4,0 Does this code really runs? The '7' is a handle for console output buffer. I think it should be received by calling GetStdHandle -- is it not? The second '4' according to MSDN must be a pointer to a DWORD to receive some information. I am not sure that '4' is a pointer here. |
|||
![]() |
|
x0r4nd 13 Jun 2013, 16:20
AsmGuru62:
1.- invoke lstrcpyn,apix,apix,eax : This code works (I checked with Ollydbg) and works better than using a different variable for the buffer to copy, mainly because it is copying a smaller number of bytes (dec eax). 2. - Loking with Ollydbg I noticed is always designated 7 as output Standar handle. Works perfectly , also 3 as handle of ReadConsole. It's about reducing bytes, optimize code and get efficiency. Regards... |
|||
![]() |
|
x0r4nd 13 Jun 2013, 16:28
AsmGuru62:
About the second "4" , you are rigth, but..... it works !!!!??? I will correct it hereinafter. Added: I've corrected it and continues the same erratic behavior. |
|||
![]() |
|
bitRAKE 13 Jun 2013, 17:22
x0r4nd wrote: bitRAKE: _________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
![]() |
|
AsmGuru62 13 Jun 2013, 17:31
xOr4nd:
Always follow MSDN and your code will be better. If MSDN says that lstrcpyn sometimes causing issues when buffers overlap, then you should believe it. It does not matter that it works now. It will not work later on some different OS. Same thing with 7 as a handle. May not always be 7. I am debugging the code right now -- there are more issues, like I think that your code is recursive, i.e. it calls itself without returning from a function by just jumping to a label. Not good. I'll post some more results later. |
|||
![]() |
|
AsmGuru62 13 Jun 2013, 18:44
It is working code (see my comments marked by 'ag62'):
Code: ; --------------------------------------------------------------------------- ; FILE: A1.Asm ; DATE: June 13, 2013 ; --------------------------------------------------------------------------- format PE console entry start include 'Win32AX.Inc' ; --------------------------------------------------------------------------- section '.data' data readable writeable hIn dd 0 hOut dd 0 control TCHAR "lstrlenW",0 str_Module TCHAR "kernel32.dll",0 str_Ask TCHAR "API: ",0 str_Stop TCHAR "cmon",0 strGotIt TCHAR 13,10,13,10,"=== GOT IT !! ===",13,10,13,10,0 salto TCHAR 10,13 apix rb 127 nBytes DD ? escrito DD ? handy DD ? apw DD ? ; --------------------------------------------------------------------------- section '.code' code readable executable ;====================================================== start: ; ; Get Console handles (just in case) ; invoke GetStdHandle, STD_OUTPUT_HANDLE mov [hOut],eax invoke GetStdHandle, STD_INPUT_HANDLE mov [hIn],eax invoke GetModuleHandle,str_Module mov [handy],eax proceso: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; invoke WriteConsole,[hOut],[handy],4,nBytes,0 invoke WriteConsole,[hOut],salto,2,nBytes,0 invoke WriteConsole,[hOut],str_Ask,5,nBytes,0 invoke ReadConsole,[hIn],apix,127,escrito,0 ; ;[ag62] ; The value of [escrito] will always include 0Dh,0Ah ; Reduce it by 2 bytes and store it back to [escrito] ; mov eax, [escrito] sub eax, 2 mov [escrito], eax ; ; Now terminate the text at apix by 00h ; mov [eax + apix], ah ; ; lets terminate if you type "cmon" ; invoke lstrcmp, str_Stop, apix test eax, eax jz kill_me ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; call llamada ; jmp kill_me ; [ag62] -- unreachable code! ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; llamada: ;popad [ag62: why? PUSHAD is never used before calling it] mov eax,[handy] mov ebp, eax mov eax, [ebp+3ch] mov eax, [eax+ebp+78h] add eax, ebp mov ecx, eax mov eax, [eax+20h] add eax, ebp mov ebx, eax ;;;;;;;;;;;;;;;;;;;;;;;;;;; sfunc: ; xor edi, edi ; ;;;;;;;;;;;;;;;;;;;;;;;;;;; finhsh: ; inc edi ; mov esi, [ebx+edi*4] ; add esi, ebp ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mostrar: ; pushad ; mov [apw],esi ; ; ; [ag62] So, every API name in KERNEL32 is 10 characters? ; lets count them and pass a proper parameter. ; invoke lstrlenA, esi invoke WriteConsole,[hOut],esi,eax,nBytes,0 invoke WriteConsole,[hOut],salto,2,nBytes,0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; push [escrito] ;ByVal cchCount2 As Long ;-1 ; ; push apix ;ByVal lpString2 As String ; ; push [escrito] ;ByVal cchCount1 As Long ;-1 ; [ag62] must be lstrlenA(apw) ; push [apw] ;ByVal lpString1 As String ;esi ; ; push 0x01 ;ByVal dwCmpFlags As Long, ; ; push 0x0400 ;ByVal Locale As Long, ; ; call [CompareString] ;As Long ; ; cmp eax,2 ;Const CSTR_EQUAL = 2 ; ; je proceso ; start ; ; ; [ag62] just using the good old Win API ; invoke lstrcmp,esi,apix test eax, eax jz found_apix ; ; [ag62] ; so, 'lstrlenW' is the last one in K32? ; if not (in other OS version) -- your code will be looking beyond 'lstrlenW'. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; invoke lstrcmp,esi,control ; cmp eax,0 ; ; ; [ag62] You're JMP-ing to outside label from a CALL-ed function. ; I'll do the same at 'found_apix' label, but you need to try to ; do it properly. Also, how do you end this code? what do ; you type at "API" prompt to end it? ; je proceso ;start ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; popad ; jmp finhsh ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; found_apix: invoke lstrlenA, strGotIt invoke WriteConsole,[hOut],strGotIt,eax,nBytes,0 jmp proceso kill_me: invoke ExitProcess, 0 ; --------------------------------------------------------------------------- section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',user32,'USER32.DLL' include 'API\Kernel32.Inc' include 'API\User32.Inc' |
|||
![]() |
|
x0r4nd 13 Jun 2013, 22:39
Thank you very much AsmGuru62.
Your code works perfectly. It is a great help. I hope to finish my project and post it for more advice and refine. As you know every step in the way there are new obstacles, much more to me that I am just learning assembly, I never understood the C + + and all my knowledge was limited to some VBA and VBscript. Apologize for the language mistakes , I write in Spanish and translate it via Google. Added some comments to your comments. Quote: ;[ag62] |
|||
![]() |
|
AsmGuru62 14 Jun 2013, 00:41
Great research!
I'll try to answer some of your questions. 1. Once llamada is called it never returns back. You use JMP to return back to the asking which API must be located. Therefore code AFTER call to llamada cannot be reached, such case is called an unreachable code. 2. lstrcmp or CompareString? It depends on your needs. For example, if you type "HeapFree" running the code I posted - it will be found by lstrcmp. but if you type "heapfree" - it will not be found, but CompareString will find it. 3. "cmon" is short for this (it has quite a lot of meanings): http://thesaurus.com/browse/come+on?s=t&path=/ |
|||
![]() |
|
x0r4nd 14 Jun 2013, 17:22
Again thanks to you asmguru62 and all who contribute with their ideas and advice.
Where do I find the button to mark solved the topic? |
|||
![]() |
|
AsmGuru62 14 Jun 2013, 17:34
I am not sure these forums have such feature.
|
|||
![]() |
|
typedef 14 Jun 2013, 21:49
x0r4nd wrote: Again thanks to you asmguru62 and all who contribute with their ideas and advice. Do it my way. Add this to the topic: [SOLVED] |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.