News:

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

Get Function Name

Started by 2-Bit Chip, August 23, 2009, 03:32:45 AM

Previous topic - Next topic

dedndave

this works too...

        INVOKE  SomeErrorProneFunction,parm2,parm1
        or      eax,eax
        jnz     Successful
        push dword ptr @Line-3  ;adjust to point to the invoke line
        INVOKE  GetLastError
        pop     edx

jj2007

What would have been really cool: If M$ had decided to store the address of the function that called SetLastError...

Here_I_am:
invoke SetLastError, ERROR_INVALID_NAME


00401031       |.  6A 7B                   push 7B                           ; /Error = ERROR_INVALID_NAME
00401033       |.  E8 BA000000             call <jmp.&kernel32.SetLastError> ; \SetLastError
...
004010F2        $- FF25 68114000           jmp near [<&kernel32.SetLastError>;  ntdll.RtlSetLastWin32Error
...
RtlSetLastWin3>  8BFF                      mov edi, edi                      ; ntdll.7C920738
7C920342         55                        push ebp
7C920343         8BEC                      mov ebp, esp
7C920345         64:A1 18000000            mov eax, fs:[18]
7C92034B         8B4D 08                   mov ecx, [ebp+8]
7C92034E         8948 34                   mov [eax+34], ecx
7C920351         5D                        pop ebp
7C920352         C2 0400                   retn 4


Interesting proc, isn't it? 50% are just useless; this should do the job:
7C920345         64:A1 18000000            mov eax, fs:[18]
7C92034B         8B4D 08                   mov ecx, [esp+8]
7C92034E         8948 34                   mov [eax+34], ecx
7C920352         C2 0400                   retn 4


Or, a little bit shorter:
MyError proc
db 64h, 0A1h, 18h, 0h, 0h, 0h ; mov eax, fs:[18]
pop ecx
pop [eax+34h]
jmp ecx
MyError endp

dedndave

i have developed the basis for extracting the function name, as well as the library name
we all know about the IAT jmp tables
the data table that those jumps point to gets adjusted at load-time (relocated) to indicate the function addresses
but !   :bg  there is also another copy of that table that does not get
altered at load-time that may be used to get the addresses of the strings
at the end of "our" .CONST segment definitions is a 4-aligned dword that points to the table (after adding the 400000h)

        INCLUDE \masm32\include\masm32rt.inc

        .const

OurConstDefines db 1

END_OF_CONST_SEGMENT EQU $

        .data
        .data?
        .code

start:  INVOKE  GetCurrentProcess
        mov     edx,END_OF_CONST_SEGMENT+3
        and     dl,0FCh
        mov     ecx,400000h
        mov     edx,[edx]
        add     edx,ecx
        inc     ecx
        inc     ecx

loop00: mov     eax,[edx]
        or      eax,eax
        jz      exit00

        add     eax,ecx
        push    ecx
        push    edx
        print   eax
        print   chr$(13,10)
        pop     edx
        add     edx,4
        pop     ecx
        jmp     loop00

exit00: exit

        END     start

i put GetCurrentProcess in there just to have another function in the list
GetStdHandle and WriteFile are from the print macro, of course
output:

GetCurrentProcess
GetStdHandle
WriteFile
ExitProcess

in these tables are dwords that (again, after adding the 400000h) point to the strings
each string is preceeded by a 2-aligned word value that we may ignore and terminated with a 0
there is a seperate table for each library - the tables are seperated by a dword 0
also, at the end of each string group is the name of the library that the group of functions came from
i am working on code that will also support msvcrt.dll errors....

dedndave

maybe someone in here knows how to do what i want to do
i can use FormatMessage to get API error descriptions - no problem, there
i want to apply the same technique for msvcrt.dll errors
here is my current code, to give you an idea...

include \masm32\include\masm32rt.inc

.data
DirName db 'C:\xyzzy',0    ;a path that does not exist
crtName db 'msvcrt.dll',0

.data?
ErrBuf  db 1024 dup(?)

.code
start:
push offset DirName
call crt__chdir
add esp,4
call crt__errno
push dword ptr [eax]
invoke GetModuleHandle,offset crtName
pop edx
invoke FormatMessage,FORMAT_MESSAGE_FROM_HMODULE,eax,edx,0,offset ErrBuf,1024,NULL
print offset ErrBuf
exit

end start

i am getting the correct error code (2=path not found) from errno
the module handle should be right
so, it boils down to FormatMessage not doing what i was hoping
any suggestions ?

EDIT - there aren't that many crt error codes - i suppose i could make a table and map them to winAPI codes

MichaelW

I tried a C app where I attempted to get the error descriptions with _RTC_GetErrDesc, but I could only get a few of them because _RTC_NumErrors always reported 4, even when I linked with the debug library. In any case, there is a list here.
eschew obfuscation

dedndave

thanks for the tip, Michael
that function is not part of msvcrt
it is defined in rtcapi.h
i am guessing (lol) that it is in RunTmChk.lib
i get lost looking at C code - let alone their include files - lol
the rtcapi.h file i have says these functions are deprecated
any ideas how to declare the externdef ?

Tedd

FormatMessage will try to look up a string for the error code from the module you give it a handle to - if there are none, obviously it can't find them. In general, just use FORMAT_MESSAGE_FROM_SYSTEM (as in the code I posted) - that covers all standard error codes, and many from modules that have already been loaded by the system.
No snowflake in an avalanche feels responsible.

dedndave

thanks Tedd - that part works
the msvcrt error codes are different, however
the text strings are in the msvcrt.dll file - they just aren't available as resources
i may be able to use perror or one of the other crt functions to get the strings
it's just a matter of playing with it - lol
a good experience, anyways - i get to know my way around the crt a bit

dedndave

#23
got it
crt_strerror returns the address of the string

EDIT
there are two functions, crt__strerror and crt_strerror
they don't behave like the documentation suggests (big surprise)
crt_strerror seems to be the one to use

dedndave

msvcrt.dll error message list

0       No error
1       Operation not permitted
2       No such file or directory
3       No such process
4       Interrupted function call
5       Input/output error
6       No such device or address
7       Arg list too long
8       Exec format error
9       Bad file descriptor
10      No child processes
11      Resource temporarily unavailable
12      Not enough space
13      Permission denied
14      Bad address
15      Unknown error
16      Resource device
17      File exists
18      Improper link
19      No such device
20      Not a directory
21      Is a directory
22      Invalid argument
23      Too many open files in system
24      Too many open files
25      Inappropriate I/O control operation
26      Unknown error
27      File too large
28      No space left on device
29      Invalid seek
30      Read-only file system
31      Too many links
32      Broken pipe
33      Domain error
34      Result too large
35      Unknown error
36      Resource deadlock avoided
37      Unknown error
38      Filename too long
39      No locks available
40      Function not implemented
41      Directory not empty
42      Illegal byte sequence


now, i just have to figure out crt__DOSerrno and WSAGetLastError - lol