Unnecessary variable assignation in HLIL output

Open
#4,145 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
cpp

Research direction

Use the supplied HLIL and disassembly examples as reproduction cases, focusing on 32-bit binaries using __fastcall or __thiscall. Read the linked comment for the suspected binary-specific relationship, then inspect the HLIL/decompiler behavior that creates the initial assignments. Done means unnecessary variable assignments are removed while required assignments remain correct.

Written by the indexing model from the issue text.

Description

Component: Core Core: HLIL IL Optimization Impact: Medium

Version and Platform (required):

  • Binary Ninja Version: 3.4.4164-dev
  • OS: Windows 11, x64

Bug Description:

I saw a lot of decompiler output like below. I wonder if this is a bug or a example waiting for optimization. I expect BN to get rid of that automatically.

I can share the binary if needed.

NOTE: Please read this comment, this issue could be related to some spesific binaries that uses __fastcall or __thiscall in 32 bit binaries.

void __fastcall write_to_file(char* lpFileName, void* buffer, uint32_t size)

uint32_t written = lpFileName
written = 0
HANDLE hFile = CreateFileA(lpFileName, 0x40000000, FILE_SHARE_NONE, nullptr, CREATE_ALWAYS, SECURITY_ANONYMOUS, nullptr)
if (hFile != -1) {
  WriteFile(hFile, buffer, size, &written, nullptr)
  CloseHandle(hFile)
}

Disassembly:

void __fastcall write_to_file(char* lpFileName, void* buffer, uint32_t size)

55                 push    ebp {__saved_ebp}
8bec               mov     ebp, esp {__saved_ebp}
51                 push    ecx {written}
53                 push    ebx {__saved_ebx}  {0x0}
56                 push    esi {__saved_esi}
57                 push    edi {__saved_edi}
33db               xor     ebx, ebx  {0x0}
8bfa               mov     edi, edx
53                 push    ebx {var_18}  {0x0}
53                 push    ebx {var_1c}  {0x0}
6a02               push    0x2 {var_20}
53                 push    ebx {var_24}  {0x0}
53                 push    ebx {var_28}  {0x0}
6800000040         push    0x40000000 {var_2c}
51                 push    ecx {var_30}
895dfc             mov     dword [ebp-0x4 {written}], ebx  {0x0}
ff1518914100       call    dword [CreateFileA]
8bf0               mov     esi, eax
83feff             cmp     esi, 0xffffffff
7417               je      0x415cbf

53                 push    ebx {var_18}  {0x0}
8d45fc             lea     eax, [ebp-0x4 {written}]
50                 push    eax {written} {var_1c_1}
ff7508             push    dword [ebp+0x8 {size}] {var_20_1}
57                 push    edi {var_24_1}
56                 push    esi {var_28_1}
ff15ec904100       call    dword [WriteFile]
56                 push    esi {var_18_1}
ff15fc914100       call    dword [CloseHandle]

5f                 pop     edi {__saved_edi}
5e                 pop     esi {__saved_esi}
5b                 pop     ebx {__saved_ebx}  {0x0}
c9                 leave    {__saved_ebp}
c3                 retn     {__return_addr}

Another example:

uint32_t lpNumberOfBytesRead = lpFileName
void* buffer = my_alloc(0x2800000)
lpNumberOfBytesRead = 0
HANDLE hFile = CreateFileA(lpFileName, 0x80000000, FILE_SHARE_NONE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr)
if (hFile == 0xffffffff) {
  *size_out = 0
}

Disassembly:

55                 push    ebp {__saved_ebp}
8bec               mov     ebp, esp {__saved_ebp}
51                 push    ecx {lpNumberOfBytesRead}
53                 push    ebx {__saved_ebx}  {0x0}
56                 push    esi {__saved_esi}
57                 push    edi {__saved_edi}
6800008002         push    0x2800000
8bfa               mov     edi, edx
8bf1               mov     esi, ecx
e8c4b1feff         call    my_alloc
59                 pop     ecx  {0x2800000}
8bd8               mov     ebx, eax
33c0               xor     eax, eax  {0x0}
50                 push    eax  {0x0}
6880000000         push    0x80
6a03               push    0x3
50                 push    eax  {0x0}
50                 push    eax  {0x0}
6800000080         push    0x80000000 {var_2c}  {0x80000000}
56                 push    esi {var_30}
8945fc             mov     dword [ebp-0x4 {lpNumberOfBytesRead}], eax  {0x0}
ff1518914100       call    dword [CreateFileA]
8bf0               mov     esi, eax
83feff             cmp     esi, 0xffffffff
7503               jne     0x415e64

Dominant language
C++
Stars
1.3k
Forks
298
Avg merge
5d 5h
Merged PRs (30d)
19

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Vector35/binaryninja-api

All issues in Vector35/binaryninja-api

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.