taviso / loadlibrary

Porting Windows Dynamic Link Libraries to Linux
GNU General Public License v2.0
4.34k stars 378 forks source link

mpclient: failed to resolve function #102

Closed Samuel-Bie closed 2 years ago

Samuel-Bie commented 3 years ago

HI @taviso if u can help me with this.


int __stdcall (*GetFiscalCode)(char *, char *, char *, char *, char *, char *, char *, char *, int);

int main(int argc, char **argv, char **envp)
{
    printf("Beggining");

    struct pe_image image = {
        .entry = NULL,
        .name = "engine/FiscalCode.dll",
    };
    printf("image initialized\n");

    // Load the FiscalCode module.
    if (pe_load_library(image.name, &image.image, &image.size) == false)
    {
        LogMessage("You must add the dll and vdm files to the engine directory");
        return 1;
    }

    printf("image loaded\n");

    // Handle relocations, imports, etc.
    link_pe_images(&image, 1);

    printf("Loading GetFiscalCode\n");

    if (get_export("GetFiscalCode", &GetFiscalCode) == -1)
    {
        errx(EXIT_FAILURE, "failed to resolve function");
        // errx(EXIT_FAILURE, "Failed to resolve FiscalCode entrypoint");
    }
    printf("Entrypoint GetFiscalCode found\n");

    setup_nt_threadinfo(NULL);

    char str[6] = "";
    char *fiscalCode = str;
    char nuit[] = "100000003"; //NUIT

    // $test = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALJfpGQjuq1Q5HRhEJdrQDCVLUmOTi2vwZZpPtfkVBcQHa1kcwcQG27XrrsmETySIkSYC1u5Ej8ZGhraPWMb9eeEwGSbtaaXz1BO2XgBY4c6LiL/jM+ZE8anDAdiJ7WF1lw/4G7LDlBO0tAtRrT5JOx/qicANOtStICX49I6m3gvAgMBAAECgYBLe/n/frdDHRZwwZrZ2UNCy/5sQFKJNvV/h25WwoNrdyB3/ihHduOFFrUU8dkdfuINkSJNYJZ+KUtIzc5ooK6A4bepwHj+NKOlfRt9eGGP/O3MNPOyfpBMp1IzsOkT2keNMK+YjpObeQUu77pOsJhsdLQJBGqIRvhKzbCo2YOvwQJBAP3rbauHnPbRi3zOzDVcIrXXsrf3+sZrZacKGAZ8RHT4Nhql9M3RtY+nQrB4rSyId+Nb9yPpOPM4dswIMp+MBTECQQCz1cNpexaEouuskzjzowjj1sBNMcYzBG7i4vKrunZCZ4XdL5wkAOadtmrdU45C9Hfi4K2md6C11xvja1HT13tfAkBGLoY3fNozliNZscbbkMW/QQkStCXKJfEIxE9zq3E4a0p4/xm0sZvfQrm6EQC8aFPKsaaTdGjbQOYE6tcjJg5hAkAZ8o3vekMVgCxhChz9iliOBz5X5Qaj9c/KDNTW0mCd1DIMaAIvb7HWr6tbo+Ky5nMl2SU1D62wjwkHF0UHO+AhAkBvPWZz77aSLW6F61gXIqF6NaLpuXvPL5yoiWzkUt59XOFsT5fd58pVzW14HkHwXI0RZNXeMoMv/rTEVwPch/n9";
    char privateKey[] = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALJfpGQjuq1Q5HRhEJdrQDCVLUmOTi2vwZZpPtfkVBcQHa1kcwcQG27XrrsmETySIkSYC1u5Ej8ZGhraPWMb9eeEwGSbtaaXz1BO2XgBY4c6LiL/jM+ZE8anDAdiJ7WF1lw/4G7LDlBO0tAtRrT5JOx/qicANOtStICX49I6m3gvAgMBAAECgYBLe/n/frdDHRZwwZrZ2UNCy/5sQFKJNvV/h25WwoNrdyB3/ihHduOFFrUU8dkdfuINkSJNYJZ+KUtIzc5ooK6A4bepwHj+NKOlfRt9eGGP/O3MNPOyfpBMp1IzsOkT2keNMK+YjpObeQUu77pOsJhsdLQJBGqIRvhKzbCo2YOvwQJBAP3rbauHnPbRi3zOzDVcIrXXsrf3+sZrZacKGAZ8RHT4Nhql9M3RtY+nQrB4rSyId+Nb9yPpOPM4dswIMp+MBTECQQCz1cNpexaEouuskzjzowjj1sBNMcYzBG7i4vKrunZCZ4XdL5wkAOadtmrdU45C9Hfi4K2md6C11xvja1HT13tfAkBGLoY3fNozliNZscbbkMW/QQkStCXKJfEIxE9zq3E4a0p4/xm0sZvfQrm6EQC8aFPKsaaTdGjbQOYE6tcjJg5hAkAZ8o3vekMVgCxhChz9iliOBz5X5Qaj9c/KDNTW0mCd1DIMaAIvb7HWr6tbo+Ky5nMl2SU1D62wjwkHF0UHO+AhAkBvPWZz77aSLW6F61gXIqF6NaLpuXvPL5yoiWzkUt59XOFsT5fd58pVzW14HkHwXI0RZNXeMoMv/rTEVwPch/n9";
    char key[] = "";

    char divice_code[] = "100010001003";
    char invoice_code[] = "000180110000";
    char invoice_number[] = "06103666";
    char amount[] = "117.00";
    char date[] = "20190818152515";

    // Call DllMain()
    image.entry((HANDLE)'UNKNOWN_WORD', DLL_PROCESS_ATTACH, NULL);

    GetFiscalCode(nuit, invoice_code, invoice_number, date, divice_code, amount, fiscalCode, key, 123);

    printf("%s\n", fiscalCode);

    return 0;
}

after running make and ./mpclient

it says mpclient: failed to resolve function FAIL: 1

taviso commented 3 years ago

What is the output of dumpbin.exe /exports FiscalCode.dll?

Or, if you can't use dumpbin, you can type something like: objdump -x FiscalCode.dll | awk '/The Export Tables/,/The [^E]+ Table/ { print }'

Samuel-Bie commented 3 years ago

The output

$ objdump -x FiscalCode.dll | awk '/The Export Tables/,/The [^E]+ Table/ { print }'                                                                                                                       [18:38:05]
The Export Tables (interpreted .rdata section contents)

Export Flags                    0
Time/Date stamp                 5adf6e0c
Major/Minor                     0/0
Name                            00000000000036d2 FiscalCode.dll
Ordinal Base                    1
Number in:
        Export Address Table            00000001
        [Name Pointer/Ordinal] Table    00000001
Table Addresses
        Export Address Table            00000000000036c8
        Name Pointer Table              00000000000036cc
        Ordinal Table                   00000000000036d0

Export Address Table -- Ordinal Base 1
        [   0] +base[   1] 1a90 Export RVA

[Ordinal/Name Pointer] Table
        [   0] GetFiscalCode

The Function Table (interpreted .pdata section contents)
taviso commented 3 years ago

I don't know, it seems okay - can you share the DLL?

Samuel-Bie commented 3 years ago

Yes. I Can. The dropbox link here

taviso commented 3 years ago

Oh - it's an x86-64 dll, support for x86-64 is still experimental. You can try it if you like!

https://github.com/taviso/loadlibrary/pull/97

Samuel-Bie commented 3 years ago

OK, Checking

Oh - it's an x86-64 dll, support for x86-64 is still experimental. You can try it if you like!

97

Samuel-Bie commented 3 years ago

But @taviso , how do i try x86-64, does this has its own brunch? I switched to x86-64 brunch and the last commit was 6 months ago.

cube0x8 commented 3 years ago

@Samuel-Bie here the x64 branch: https://github.com/cube0x8/loadlibrary/tree/x64

Samuel-Bie commented 3 years ago

Trying it Today. Let u know about any issue.

Samuel-Bie commented 3 years ago

I was already running tests on that brunch https://github.com/cube0x8/loadlibrary/tree/x64 , but when running make i get the following error.

make -C peloader debug ARCH=x64
make[1]: Entering directory '/home/coder/x86/peloader'
make[1]: Nothing to be done for 'debug'.
make[1]: Leaving directory '/home/coder/x86/peloader'
cd intercept; mkdir build; cd build; cmake -DARCH:STRING=x64 -DCMAKE_BUILD_TYPE=Debug ..; make
mkdir: cannot create directory ‘build’: File exists
-- The ASM_NASM compiler identification is unknown
-- Didn't find assembler
CMake Error at CMakeLists.txt:4 (enable_language):
  No CMAKE_ASM_NASM_COMPILER could be found.

  Tell CMake where to find the compiler by setting either the environment
  variable "ASM_NASM" or the CMake cache entry CMAKE_ASM_NASM_COMPILER to the
  full path to the compiler, or to the compiler name if it is in the PATH.

-- Configuring incomplete, errors occurred!
See also "/home/coder/x86/intercept/build/CMakeFiles/CMakeOutput.log".
See also "/home/coder/x86/intercept/build/CMakeFiles/CMakeError.log".
make[1]: Entering directory '/home/coder/x86/intercept/build'
make[1]: *** No targets specified and no makefile found.  Stop.
make[1]: Leaving directory '/home/coder/x86/intercept/build'
make: *** [Makefile:27: intercept] Error 2
Samuel-Bie commented 3 years ago

Hi again. @cube0x8 and @taviso .


~/x86 on  x64! ⌚ 13:40:14
$ make
cc -march=native -ggdb3 -std=gnu99 -fshort-wchar -Wno-multichar -Iinclude -Iintercept/include -Ilog -Ipeloader -mstackrealign -maccumulate-outgoing-args -O3 -D_GNU_SOURCE -I. -DNDEBUG -march=native -ggdb3 -std=gnu99 -fshort-wchar -Wno-multichar -Iinclude -Iintercept/include -Ilog -Ipeloader -mstackrealign -maccumulate-outgoing-args -O3 -lm -Wl,--dynamic-list=exports.lst -ldl  fiscalcode.c  -Wl,--whole-archive peloader/libpeloader.a -Wl,intercept/libhook.a -Wl,intercept/libZydis.a -Wl,intercept/libsubhook.a -Wl,--no-whole-archive -o fiscalcode
/usr/bin/ld: cannot find intercept/libhook.a: No such file or directory
/usr/bin/ld: cannot find intercept/libZydis.a: No such file or directory
/usr/bin/ld: cannot find intercept/libsubhook.a: No such file or directory
collect2: error: ld returned 1 exit status
make: *** [<builtin>: fiscalcode] Error 1
Samuel-Bie commented 3 years ago

make
cc -march=native -ggdb3 -std=gnu99 -fshort-wchar -Wno-multichar -Iinclude -Iintercept/include -Ilog -Ipeloader -mstackrealign -maccumulate-outgoing-args -O3 -m32 -D_GNU_SOURCE -I. -DNDEBUG  -c -o mpclient.o mpclient.c
In file included from mpclient.c:42:
peloader/winnt_types.h:2190:9: error: unknown type name ‘PM128A’
 2190 |         PM128A FloatingContext[16];
      |         ^~~~~~
peloader/winnt_types.h:2192:13: error: unknown type name ‘PM128A’
 2192 |             PM128A Xmm0;
      |             ^~~~~~
peloader/winnt_types.h:2193:13: error: unknown type name ‘PM128A’
 2193 |             PM128A Xmm1;
      |             ^~~~~~
peloader/winnt_types.h:2194:13: error: unknown type name ‘PM128A’
 2194 |             PM128A Xmm2;
      |             ^~~~~~
peloader/winnt_types.h:2195:13: error: unknown type name ‘PM128A’
 2195 |             PM128A Xmm3;
      |             ^~~~~~
peloader/winnt_types.h:2196:13: error: unknown type name ‘PM128A’
 2196 |             PM128A Xmm4;
      |             ^~~~~~
peloader/winnt_types.h:2197:13: error: unknown type name ‘PM128A’
 2197 |             PM128A Xmm5;
      |             ^~~~~~
peloader/winnt_types.h:2198:13: error: unknown type name ‘PM128A’
 2198 |             PM128A Xmm6;
      |             ^~~~~~
peloader/winnt_types.h:2199:13: error: unknown type name ‘PM128A’
 2199 |             PM128A Xmm7;
      |             ^~~~~~
peloader/winnt_types.h:2200:13: error: unknown type name ‘PM128A’
 2200 |             PM128A Xmm8;
      |             ^~~~~~
peloader/winnt_types.h:2201:13: error: unknown type name ‘PM128A’
 2201 |             PM128A Xmm9;
      |             ^~~~~~
peloader/winnt_types.h:2202:13: error: unknown type name ‘PM128A’
 2202 |             PM128A Xmm10;
      |             ^~~~~~
peloader/winnt_types.h:2203:13: error: unknown type name ‘PM128A’
 2203 |             PM128A Xmm11;
      |             ^~~~~~
peloader/winnt_types.h:2204:13: error: unknown type name ‘PM128A’
 2204 |             PM128A Xmm12;
      |             ^~~~~~
peloader/winnt_types.h:2205:13: error: unknown type name ‘PM128A’
 2205 |             PM128A Xmm13;
      |             ^~~~~~
peloader/winnt_types.h:2206:13: error: unknown type name ‘PM128A’
 2206 |             PM128A Xmm14;
      |             ^~~~~~
peloader/winnt_types.h:2207:13: error: unknown type name ‘PM128A’
 2207 |             PM128A Xmm15;
      |             ^~~~~~
mpclient.c: In function ‘main’:
mpclient.c:192:25: warning: passing argument 1 of ‘setup_nt_threadinfo’ from incompatible pointer type [-Wincompatible-pointer-types]
  192 |     setup_nt_threadinfo(ExceptionHandler);
      |                         ^~~~~~~~~~~~~~~~
      |                         |
      |                         EXCEPTION_DISPOSITION (*)(struct _EXCEPTION_RECORD *, struct _EXCEPTION_FRAME *, struct _CONTEXT *, struct _EXCEPTION_FRAME **) {aka enum <anonymous> (*)(struct _EXCEPTION_RECORD *, struct _EXCEPTION_FRAME *, struct _CONTEXT *, struct _EXCEPTION_FRAME **)}
In file included from mpclient.c:43:
peloader/pe_linker.h:1121:45: note: expected ‘PEXCEPTION_HANDLER’ {aka ‘enum <anonymous> (*)(struct _EXCEPTION_RECORD *, struct _EXCEPTION_FRAME *, void **, struct _EXCEPTION_FRAME **)’} but argument is of type ‘EXCEPTION_DISPOSITION (*)(struct _EXCEPTION_RECORD *, struct _EXCEPTION_FRAME *, struct _CONTEXT *, struct _EXCEPTION_FRAME **)’ {aka ‘enum <anonymous> (*)(struct _EXCEPTION_RECORD *, struct _EXCEPTION_FRAME *, struct _CONTEXT *, struct _EXCEPTION_FRAME **)’}
 1121 | bool setup_nt_threadinfo(PEXCEPTION_HANDLER handler);
      |                          ~~~~~~~~~~~~~~~~~~~^~~~~~~
mpclient.c:240:34: warning: assignment to ‘DWORD (*)(FILE *, uint64_t,  void *, DWORD,  uint32_t *)’ {aka ‘unsigned int (*)(struct _IO_FILE *, long long unsigned int,  void *, unsigned int,  unsigned int *)’} from incompatible pointer type ‘DWORD (*)(void *, ULONGLONG,  void *, DWORD,  uint32_t *)’ {aka ‘unsigned int (*)(void *, long long unsigned int,  void *, unsigned int,  unsigned int *)’} [-Wincompatible-pointer-types]
  240 |     ScanDescriptor.Read          = ReadStream;
      |                                  ^
mpclient.c:241:34: warning: assignment to ‘DWORD (*)(FILE *, uint64_t *)’ {aka ‘unsigned int (*)(struct _IO_FILE *, long long unsigned int *)’} from incompatible pointer type ‘DWORD (*)(void *, uint64_t *)’ {aka ‘unsigned int (*)(void *, long long unsigned int *)’} [-Wincompatible-pointer-types]
  241 |     ScanDescriptor.GetSize       = GetStreamSize;
      |                                  ^
mpclient.c:242:34: warning: assignment to ‘uint16_t * (*)(FILE *)’ {aka ‘short unsigned int * (*)(struct _IO_FILE *)’} from incompatible pointer type ‘uint16_t * (*)(void *)’ {aka ‘short unsigned int * (*)(void *)’} [-Wincompatible-pointer-types]
  242 |     ScanDescriptor.GetName       = GetStreamName;
      |                                  ^
make: *** [<builtin>: mpclient.o] Error 1
cube0x8 commented 3 years ago

Hello @Samuel-Bie,

first of all, thank you for reporting these issues. I realized I left some NASM dependency which is not necessary any longer. I removed it.

Please, pull the new modification I pushed on the x64 branch, clean the workspace (make clean) and try to build your target again.

Meanwhile, I will try it on my machine too with the DLL you shared.

cube0x8 commented 3 years ago

So,

I downloaded your DLL and managed to load it and link it correctly. Then, the DLL did some call to some MSVCRT.dll (the windows runtime) API, which are not implemented in loadlibrary, so it SIGSEGVs.

Here some suggestions:

1) please, when you compile your DLL, link the windows runtime statically in the binary. Here is an how-to for VS:

2) in the GetFiscalCode prototype, replace __stdcall with WINAPI: int WINAPI (*GetFiscalCode)(char *, char *, char *, char *, char *, char *, char *, char *, int);

3) You need to delcare the pe_image struct globally, so: struct pe_image image = { .entry = NULL, .name = "engine/FiscalCode.dll", }; goes before the main, right after the include statements

Please, try the points above and let me know!

cube0x8 commented 3 years ago

Hello @Samuel-Bie,

Did you manage to get your DLL working?

cube0x8 commented 2 years ago

This can be considered closed, since I managed to load and link the library shared by @Samuel-Bie and there have not been other follow ups.