Ward

BinaryCall UDF - Write Subroutines In C, Call In AutoIt

31 posts in this topic




This UDF is not for dll. To use dll, you can build dll file and then use it by DllCall, or use MemoryDll UDF.

1 person likes this

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites

This is a great tool for improving scripts that rely on complex equations.

Thanks, I might use it over compiling a .dll in some cases

1 person likes this

"Just be fred, all we gotta do, just be fred."  -Vocaliod

"That is a Hadouken. A KAMEHAMEHA would have taken him 13 days and 54 episodes to form." - Roden Hoxha

@tabhooked

Clock made of cursors ♣ Desktop Widgets ♣ Water Simulation

Share this post


Link to post
Share on other sites

Thanks! In fact, I wrote code relocation generator, GAS To FASM string converter, and memory search routine in AutoIt at first. But I found they had terrible speed for large files. So I rewrote them in C. The embedded FASM, LZMA, and Base64 routines are generated by BinaryCall Tool, too.


新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites

BinaryCall UDF and BinaryCall Tool v1.1 are released.

Following open source projects are tested and works in this version.

SQLite 3.8.5

TCC 0.9.26

PuTTY beta 0.63


新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites

I searched the zip file for SQLite example but I guess that's not supposed to be there.

I was just thinking about combining this UDF with SQLite UDF, guess it will be much faster.

Also I will be so thankful if you could give a little more explaintion about converting the C source to this, I'm not so familiar with GCC compiler as I always use Microsoft Visual C++, could CodeBlocks be used?

I really like to use this, I want to convert some of my C functions and call them without having to export them in DLLs, but unfortunately I don't have enough knowledge to get this to work.

Thanks in advance.

Share this post


Link to post
Share on other sites

This is spectacular Ward damn, your work puts most to shame, thankyou for sharing :)

Share this post


Link to post
Share on other sites

I finally managed to use it, seems interesting.

I convert some of my C functions to this and they are just awesome.

The only question I would like to ask is "Which method is faster and of course needs less memory? Using this UDF or exporting the functions in a Dll and using DllCall?"

Thanks Ward, it's a huge work, keep it up.

Share this post


Link to post
Share on other sites

I am glad to heard it, FaridAgl. It's not hard, right?

I think the speed should be equal to DLL.

Memory usage maybe need some test to say.

However, It has much more fun than DLL.


新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites

Yes, the hardest part was compiling the C source using GCC, next steps were simple.

I will run some tests and will post the result.

And of course, it's much more fun than DllCall.

Share this post


Link to post
Share on other sites

That's a pretty nice work Ward. :graduated:

All seems to work well but my symbols have decorated names.


When the words fail... music speaks

Share this post


Link to post
Share on other sites

Ward, I run in some problems while trying to convert this function:

#include <windows.h>
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")

BOOL IsConnectedToServer(DWORD dwProcessId)
{
    DWORD dwSize = 0;
    if (GetExtendedTcpTable(0, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_CONNECTIONS, 0) != ERROR_INSUFFICIENT_BUFFER)
        return FALSE;

    HANDLE hHeap = GetProcessHeap();

    LPVOID lpTcpTable = HeapAlloc(hHeap, 0, dwSize);
    if (lpTcpTable == NULL)
        return FALSE;

    if (GetExtendedTcpTable(lpTcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_CONNECTIONS, 0) != NO_ERROR)
    {
        HeapFree(hHeap, 0, lpTcpTable);
        return FALSE;
    }

    DWORD i;
    MIB_TCPROW_OWNER_PID TcpTable;
    for (i = 0; i < ((PMIB_TCPTABLE_OWNER_PID)lpTcpTable)->dwNumEntries; i++)
    {
        TcpTable = ((PMIB_TCPTABLE_OWNER_PID)lpTcpTable)->table[i];
        if (TcpTable.dwOwningPid == dwProcessId && TcpTable.dwRemotePort == 0xEF21)
        {
            HeapFree(hHeap, 0, lpTcpTable);
            return TRUE;
        }
    }

    HeapFree(hHeap, 0, lpTcpTable);
    return FALSE;
}

I have compiled it using GCC to this:

.file   "Test.c"
    .intel_syntax noprefix
    .text
    .globl  _IsConnectedToServer
    .def    _IsConnectedToServer;   .scl    2;  .type   32; .endef
_IsConnectedToServer:
    push    ebp
    mov ebp, esp
    push    edi
    push    esi
    push    ebx
    sub esp, 92
    mov DWORD PTR [ebp-40], 0
    mov DWORD PTR [esp+20], 0
    mov DWORD PTR [esp+16], 4
    mov DWORD PTR [esp+12], 2
    mov DWORD PTR [esp+8], 1
    lea eax, [ebp-40]
    mov DWORD PTR [esp+4], eax
    mov DWORD PTR [esp], 0
    call    _GetExtendedTcpTable
    cmp eax, 122
    je  L2
    mov eax, 0
    jmp L9
L2:
    call    _GetProcessHeap@0
    mov DWORD PTR [ebp-32], eax
    mov eax, DWORD PTR [ebp-40]
    mov DWORD PTR [esp+8], eax
    mov DWORD PTR [esp+4], 0
    mov eax, DWORD PTR [ebp-32]
    mov DWORD PTR [esp], eax
    call    _HeapAlloc@12
    sub esp, 12
    mov DWORD PTR [ebp-36], eax
    cmp DWORD PTR [ebp-36], 0
    jne L4
    mov eax, 0
    jmp L9
L4:
    mov DWORD PTR [esp+20], 0
    mov DWORD PTR [esp+16], 4
    mov DWORD PTR [esp+12], 2
    mov DWORD PTR [esp+8], 1
    lea eax, [ebp-40]
    mov DWORD PTR [esp+4], eax
    mov eax, DWORD PTR [ebp-36]
    mov DWORD PTR [esp], eax
    call    _GetExtendedTcpTable
    test    eax, eax
    je  L5
    mov eax, DWORD PTR [ebp-36]
    mov DWORD PTR [esp+8], eax
    mov DWORD PTR [esp+4], 0
    mov eax, DWORD PTR [ebp-32]
    mov DWORD PTR [esp], eax
    call    _HeapFree@12
    sub esp, 12
    mov eax, 0
    jmp L9
L5:
    mov DWORD PTR [ebp-28], 0
    jmp L6
L8:
    mov ecx, DWORD PTR [ebp-36]
    mov edx, DWORD PTR [ebp-28]
    mov eax, edx
    sal eax
    add eax, edx
    sal eax, 3
    add eax, ecx
    lea edx, [ebp-64]
    lea ebx, [eax+4]
    mov eax, 6
    mov edi, edx
    mov esi, ebx
    mov ecx, eax
    rep movsd
    mov eax, DWORD PTR [ebp-44]
    cmp eax, DWORD PTR [ebp+8]
    jne L7
    mov eax, DWORD PTR [ebp-48]
    cmp eax, 61217
    jne L7
    mov eax, DWORD PTR [ebp-36]
    mov DWORD PTR [esp+8], eax
    mov DWORD PTR [esp+4], 0
    mov eax, DWORD PTR [ebp-32]
    mov DWORD PTR [esp], eax
    call    _HeapFree@12
    sub esp, 12
    mov eax, 1
    jmp L9
L7:
    inc DWORD PTR [ebp-28]
L6:
    mov eax, DWORD PTR [ebp-36]
    mov eax, DWORD PTR [eax]
    cmp eax, DWORD PTR [ebp-28]
    ja  L8
    mov eax, DWORD PTR [ebp-36]
    mov DWORD PTR [esp+8], eax
    mov DWORD PTR [esp+4], 0
    mov eax, DWORD PTR [ebp-32]
    mov DWORD PTR [esp], eax
    call    _HeapFree@12
    sub esp, 12
    mov eax, 0
L9:
    lea esp, [ebp-12]
    pop ebx
    pop esi
    pop edi
    pop ebp
    ret
    .def    _GetExtendedTcpTable;   .scl    2;  .type   32; .endef
    .def    _GetProcessHeap@0;  .scl    2;  .type   32; .endef
    .def    _HeapAlloc@12;  .scl    2;  .type   32; .endef
    .def    _HeapFree@12;   .scl    2;  .type   32; .endef

But your convertor says:

 

Unresolved external symbol: "_GetExtendedTcpTable"

and fails.

Share this post


Link to post
Share on other sites

Your code uses "GetExtendedTcpTable" API

According to MSDN, it requires "Iphlpapi.dll".

This dll is not declared in BinaryCall.inc by default.

To declare it, add following line to BinaryCall.inc

def_api iphlpapi.dll,10,GetExtendedTcpTable

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

Thanks Ward, that makes sense and I understood that line.

Just to make it more clear, what is the number "10", in that line?

Edit:

I got it, it's the order you gave them.

Edited by FaridAgl

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

Yes, I already declared following frequency used DLL in BinaryCall.inc (number 1~9).

  1. kernel32.dll
  2. user32.dll
  3. gdi32.dll
  4. shell32.dll
  5. advapi32.dll
  6. comctl32.dll
  7. comdlg32.dll
  8. wsock32.dll
  9. msvcrt.dll
So, if the DLL you used is not here, you must declare it by yourself.
Edited by Ward
1 person likes this

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites

I got an error when I tried to make this function to work:

// Credits to matwachich
// http://www.autoitscript.com/forum/topic/150905-need-advise-on-my-wsa-tcp-functions-c/?p=1078769

#define _WIN32_WINNT 0x501
#include <ws2tcpip.h>

int TCPConnect (const char* host, const char* port)
{
    struct addrinfo hints, *result = NULL;
    ZeroMemory(&hints, sizeof(hints));

    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    if (getaddrinfo(host, port, &hints, &result) != 0) {
        return 0;
    }

    SOCKET ConnectSocket = INVALID_SOCKET;
    ConnectSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ConnectSocket == INVALID_SOCKET) {
        freeaddrinfo(result);
        return 0;
    }

    if (connect(ConnectSocket, result->ai_addr, (int)result->ai_addrlen) != 0) {
        freeaddrinfo(result);
        return 0;
    }
    freeaddrinfo(result);

    unsigned long mode = 1;
    if (ioctlsocket(ConnectSocket, FIONBIO, &mode) != 0) {
        return 0;
    }

    return ConnectSocket;
}

Using gcc I got this asm file

.file   "prog.cpp"
    .intel_syntax noprefix
    .text
    .globl  __Z10TCPConnectPKcS0_
    .def    __Z10TCPConnectPKcS0_;  .scl    2;  .type   32; .endef
__Z10TCPConnectPKcS0_:
LFB8:
    .cfi_startproc
    .cfi_personality 0,___gxx_personality_v0
    .cfi_lsda 0,LLSDA8
    push    ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    mov ebp, esp
    .cfi_def_cfa_register 5
    sub esp, 72
    mov DWORD PTR [ebp-16], 0
    mov DWORD PTR [esp+8], 32
    mov DWORD PTR [esp+4], 0
    lea eax, [ebp-52]
    mov DWORD PTR [esp], eax
    call    _memset
    mov DWORD PTR [ebp-48], 2
    mov DWORD PTR [ebp-44], 1
    mov DWORD PTR [ebp-40], 6
    lea eax, [ebp-16]
    mov DWORD PTR [esp+12], eax
    lea eax, [ebp-52]
    mov DWORD PTR [esp+8], eax
    mov eax, DWORD PTR [ebp+12]
    mov DWORD PTR [esp+4], eax
    mov eax, DWORD PTR [ebp+8]
    mov DWORD PTR [esp], eax
LEHB0:
    call    _getaddrinfo@16
    sub esp, 16
    test    eax, eax
    setne   al
    test    al, al
    je  L2
    mov eax, 0
    jmp L10
L2:
    mov DWORD PTR [ebp-12], -1
    mov eax, DWORD PTR [ebp-16]
    mov ecx, DWORD PTR [eax+12]
    mov eax, DWORD PTR [ebp-16]
    mov edx, DWORD PTR [eax+8]
    mov eax, DWORD PTR [ebp-16]
    mov eax, DWORD PTR [eax+4]
    mov DWORD PTR [esp+8], ecx
    mov DWORD PTR [esp+4], edx
    mov DWORD PTR [esp], eax
    call    _socket@12
    sub esp, 12
    mov DWORD PTR [ebp-12], eax
    cmp DWORD PTR [ebp-12], -1
    jne L4
    mov eax, DWORD PTR [ebp-16]
    mov DWORD PTR [esp], eax
    call    _freeaddrinfo@4
    sub esp, 4
    mov eax, 0
    jmp L10
L4:
    mov eax, DWORD PTR [ebp-16]
    mov eax, DWORD PTR [eax+16]
    mov edx, eax
    mov eax, DWORD PTR [ebp-16]
    mov eax, DWORD PTR [eax+24]
    mov DWORD PTR [esp+8], edx
    mov DWORD PTR [esp+4], eax
    mov eax, DWORD PTR [ebp-12]
    mov DWORD PTR [esp], eax
    call    _connect@12
    sub esp, 12
    test    eax, eax
    setne   al
    test    al, al
    je  L5
    mov eax, DWORD PTR [ebp-16]
    mov DWORD PTR [esp], eax
    call    _freeaddrinfo@4
    sub esp, 4
    mov eax, 0
    jmp L10
L5:
    mov eax, DWORD PTR [ebp-16]
    mov DWORD PTR [esp], eax
    call    _freeaddrinfo@4
    sub esp, 4
    mov DWORD PTR [ebp-20], 1
    mov eax, 4
    and eax, 127
    sal eax, 16
    or  eax, -2147457410
    lea edx, [ebp-20]
    mov DWORD PTR [esp+8], edx
    mov DWORD PTR [esp+4], eax
    mov eax, DWORD PTR [ebp-12]
    mov DWORD PTR [esp], eax
    call    _ioctlsocket@12
LEHE0:
    sub esp, 12
    test    eax, eax
    setne   al
    test    al, al
    je  L6
    mov eax, 0
    jmp L10
L6:
    mov eax, DWORD PTR [ebp-12]
    jmp L10
L9:
    mov DWORD PTR [esp], eax
LEHB1:
    call    __Unwind_Resume
LEHE1:
L10:
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
LFE8:
    .def    ___gxx_personality_v0;  .scl    2;  .type   32; .endef
    .section    .gcc_except_table,"w"
LLSDA8:
    .byte   0xff
    .byte   0xff
    .byte   0x1
    .uleb128 LLSDACSE8-LLSDACSB8
LLSDACSB8:
    .uleb128 LEHB0-LFB8
    .uleb128 LEHE0-LEHB0
    .uleb128 L9-LFB8
    .uleb128 0
    .uleb128 LEHB1-LFB8
    .uleb128 LEHE1-LEHB1
    .uleb128 0
    .uleb128 0
LLSDACSE8:
    .text
    .ident  "GCC: (GNU) 4.8.1"
    .def    _memset;    .scl    2;  .type   32; .endef
    .def    _getaddrinfo@16;    .scl    2;  .type   32; .endef
    .def    _socket@12; .scl    2;  .type   32; .endef
    .def    _freeaddrinfo@4;    .scl    2;  .type   32; .endef
    .def    _connect@12;    .scl    2;  .type   32; .endef
    .def    _ioctlsocket@12;    .scl    2;  .type   32; .endef
    .def    __Unwind_Resume;    .scl    2;  .type   32; .endef

I added manually in BinaryCall.inc this line

def_adr ws2_32.dll,10,getaddrinfo,socket,freeaddrinfo,connect,ioctlsocket

When I use GAS2AU3 Converter I got this error

 

---------------------------
Flat Assembler Error: -108
---------------------------
ILLEGAL_INSTRUCTION

LINE NUMBER: 3048

ERROR LINE: "    .uleb128 LLSDACSE8-LLSDACSB8"


When the words fail... music speaks

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

  1. Try to use "gcc", not "g++" to compile the source code. (.uleb128 pseudo-op not yet support).
  2. You should use "def_api", not "def_adr". They are different.
  3. You use "ws2_32.dll", so the line "def_api wsock32.dll" may need be deleted (or add ";" to set as comment)
Edited by Ward

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

This is very cool. Can you explain a bit more about the def_api (well, I think I get this one), def_api_ (with the extra _ ), def_adr, and def_label lines in the .inc file?

Edited by wraithdu

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • ur
      By ur
      Is there anyway to create an assembly for AutoIT so that I can use that in Powershell or Dotnet supported languages like c#.
      Like I want to use the functionality of _ArrayDisplay of AutoIT in C# by creating a assmbly/library and using that in the target language.
    • wakillon
      By wakillon
      BinaryToAu3Kompressor v1.0.5.4
       

       
      It's now possible to see the best compression ratio using LZMA, LZNT and Base64 compressions with differents combinations.
      Nothing too complicate, you drag'n drop a file on the picture and script Test all compression types and return the ratios.
      ( Test duration depends of file size, slowest compression is LZNT, but all decompressions are fast  )
      Free to you after, to choose the compression(s) you want...
      Yes, LZMA needs a dll ( embedded & compressed in script ) but brings a powerfull compression. 
      It opens scite with your file compressed to an au3 script with or without decompression function as you want.
      Hold Left Shift key when clicking button for just copy script to clipboard.
      Use the 3 compressions at a time works but doesn't give a good ratio, that's why i don't display it.
      Usefull for little files you want include in your scripts !
      No externals files needed, they are already in script.
      Previous downloads : 1103
      Source and Executable
      BinaryToAu3Kompressor will be added to the next version of >SciTEHopper
      Thanks to Ward for his >Base64.au3 and LZMA.au3, and trancexx for his >LZNT functions and his >Base64Decode function.
    • WoodGrain
      By WoodGrain
      Hi All,
      Trying to convert a number to binary zeros and ones but I'm getting a result I don't understand and looks more like hex than binary.
      Here's my basic code:
      $myNum = 11 $myNumBin = Binary($myNum) MsgBox(0, "Binary result", $myNumBin) What I want is "1011", what I get is 0x0B000000.
      Thanks!
    • dejhost
      By dejhost
      Hello ,
      Here are three stepts that I would like to speed up - if possible: 
      STEP 1: I am generating an array, containing binary numbers  up to a certain amount of digits. My script adds leading zeros, so that each number has equal amount of digits.
      Example: 14 digit Binary array:
      I am using the code
      For $i = 0 to 2^$bit-1 ; $bit amount of digits. for example: 14 $binary = ( Dec2Bin($i) ) ; Check length of binary string $adig = $bit - StringLen($binary) ; Determine how many leading 0 have to be added $zeros = "" For $j = 1 To $adig ; add leading "0"s $zeros = $zeros & "0" Next $BinArray[$i] = $zeros & $binary ;Write binary-number to file, leading "0" Next Func Dec2Bin($D) Return (BitShift($D, 1) ? Dec2Bin(BitShift($D, 1)) : "") & BitAnd($D, 1) EndFunc ;==> Dec2Bin() AutoIt v3.3.12.0   to generate the binary number. 
      STEP 2: I reduce the array to unique values. In my application, the binary-numbers do not have a start-bit or end-bit. This means, that
        are actually the same numbers, and only one of them is to remain in the array. All alterations aren't unique and shall be removed. Here is my code:
      For $i = 0 to Ubound($BinArray)-1 ; shift through all rows For $j = 1 to $bit ; shift through all the bits If $i = Ubound($BinArray) Then ; exit before exceeding the arrays boundries ExitLoop 2 EndIf $BinArray[$i] = StringRight ( $BinArray[$i], 1 ) & StringLeft ( $BinArray[$i], $bit-1 ) $BinArray = _ArrayUnique($BinArray, 0, 0, 0, 0, $ARRAYUNIQUE_AUTO) If @error <> 0 Then Msgbox(0, "Error in _ArrayUnique", "The Error Code is " & @error & " Abort.") Exit EndIf Next Next STEP 3: Finally, I write the remaining array into a text-file.
      For $i = 0 to Ubound($BinArray)-1 FileWrite($hFileOpen, $i & @TAB & $BinArray[$i] & @CRLF) Next  
      So my question is: any idea how to speed up this procedure? There certainly is a way to do this smarter. Btw.: Step 2 is optional.
      Thanks for helping,
      dejhost 
    • am632
      By am632
      Hi,
      I have a binary string that I want to convert to octal, The string I want to convert is,
      10001001010100000100111001000111000011010000101000011010
       
      The String is read from a .txt file
      Once its converted it should read this,
      4   2   2   5   0   1   1   6   2   1   6   0   6   4   1   2   0   6   10
      which I want written to the .txt file to overwrite the original binary string.
      The 10 at the end should be ignored as there are not 3 digits to convert.
      I'm thinking it should read the string from left to right to get the next 3 digits before converting them to its oct value. would this be the best way to do this or is there a better way?
      If i'm on the right track can anyone give me an example of how to write this script please?
      I've looked at the StringLeft function & StringReplace but I'm not sure how to use them the correct way to accomplish what I'm trying to do.
      Thanks