Showing posts with label Assembly. Show all posts
Showing posts with label Assembly. Show all posts

Wednesday, October 19, 2022

IDA Pro Reversing notes

 Notes just for me learning


CPPEH_RECORD = exception handling

__guard_check_icall_fptr = control flow guard

_initterm = creation function pointer table


Monday, April 13, 2020

C++ Console App in IDA Pro find Actual Main Function

In C++

XorTesting.exe

has

XorTesting.cpp

which looks like

int main(int argc, char * argv[])
{
    if ((argc == 3 && strlen(argv[1]) == 1 && argv[1][0] == '0') ||
        (argc == 2 && strlen(argv[1]) == 1 && argv[1][0] == '1'))
    {
            .... more code ....
    }
}

----------
In IDA Pro here is how to find the actual main function
----------

----------
start proc
   jmp start_0
----------

----------
start_0 proc
   push ebp
   mov ebp, esp
   call sub_xxxxx1 (just calls init functions)
   pop ebp
   return
-----------

-----------
sub_xxxxx1 proc
  push ebp
  mov ebp, esp
  call sub_xxxxx2  (security cookie check)
  call sub_xxxxx3  (initializes and then calls actual main function)
  pop ebp
  ret
-----------

-----------
sub_xxxxx3 proc
  var_44= dword ptr -44h
  var_40= dword ptr -40h
  var_3C= dword ptr -3Ch
  ... many more ...
  push ebp
  mov ebp, esp
  push 0FFFFFFFEh
  ...
  call j__initterm
  ...
  call ds:___guard_check_icall_fptr
  ...
  call j__register_threat_local_exe_atexit_callback
  add esp, 4
  loc_xxxxxx:
    call sub_xxxxx4 (will end up calling the actual main function)
    ...
    call j_exit
    ... lots more code...
------------


------------
sub_xxxxx4 proc
  var_C= dword ptr -0Ch
  var_8= dword ptr -8h
  var_4= dword ptr -4h
  push ebp
  mov ebp, esp
  ...
  call j__get_initial_narrow_environment
  ...
  call j__p___argv
  ...
  call j__p___argc
  ...
  call j__sub_xxxxx5   (will end up calling the actual main function)
  add esp, 0Ch
  mov esp, ebp
  pop ebp
  return
-------------

-------------
sub_xxxxx5 proc
  jmp sub_xxxxx6   (the ACTUAL main function code)
-------------

-------------
sub_xxxxx6 proc
  var_178= dword ptr -178h
  var_174= dword ptr -174h
  var_168= dword ptr -168h
  ... many more ...
  push ebp
  mov ebp, esp
  sub esp, 178h
  ...
  rep stosd
  mov eax, __security_cookie
  ...
  cmp [ebp+arg_0], 3       (equivalent of C++   "if argc == 3")
  ...
  call j_strlen          (equivalent of c++ 'strlen' call)
  ... rest of code ...
-------------

Tuesday, March 10, 2020

shellcode in ASM to C program examples

not optimized for shortness
does not remove null (00) characters

--------
using data
--------
section .text
 global _start

_start:
 xor rdi, rdi ;null char to term string
 push rdi
 mov rdi, 0x68732f6e69622f2f ; //bin/sh
 push rdi
 mov rdi, rsp ; filename
 mov rsi, 0 ; argv
 mov rdx, 0 ;envp
 mov rax, 59 ; execve syscall
 syscall

--------
using push
--------
section .data
 sh: db "//bin/sh"

section .text
 global _start

_start:
 mov rdi, sh ; filename
 mov rsi, 0 ; argv
 mov rdx, 0 ;envp
 mov rax, 59 ; execve syscall
 syscall




------
to compile
------
$> nasm -f elf64 mycode.asm -o mycode
$> ld mycode.o -o mycode
$> ./mycode
# whoami
root

Monday, January 15, 2018

msvbvm60.DllFunctionCall with kernel32.VirtualAlloc windows api

So I was reviewing an executable in x32dbg and came across this call


Now I'm just learning, so I can't claim to fully understand this, but here is my interpretation.  I think it's possible that all the lines using the floating point registers (xmm , mm, etc.) are just obfuscation and an attempt by the attacker to distract the security analyst.  I think the relevant information are the pushes and the call statement at the end. Now when we get to that call, here is what is in the registers and on the stack.

What this looks like to me is an attempt for a VB6 program to utilize the DllFunctionCall windows api to execute the kernel32.VirtualAlloc windows api, which is used typically by attackers to allocate more memory in the current process in order to inject their malicious code inside.


GetModuleFileName windows api

Here's how I understand the GetModuleFileName windows api. It takes 3 parameters, the size of the size of the buffer of where to store the filepath, the pointer to a buffer where to store the file path, and a handle to the module that you need the file path of.  In this case 0x104 is the size of the buffer, eax holds the pointer to the buffer, and the <&Ordinal958> is the handle to the module we want the filepath loaded of.


In this case the buffer in eax is 0x0018FB68 which is empty

The <&Ordinal958> was on the stack at 0x0018F858, which before execution contains the value 0x72940000
Which we can confirm/see below contains the actual DLL for which we're getting the filepath for (notice the MZ magic text on the right)
Now after the GetModuleFileName is executed, then the buffer that was in EAX, 0x0018FB68 contains now the full file path of where that DLL was located on the hard drive.

SetErrorMode windows api

Here's how I understand the SetErrorMode windows api. It takes one parameter, the mode which is a bunch of bitwise flags that can be set toggling certain error features on and off.


In this case 8001 was passed as the flags.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v=vs.85).aspx

MSDN says that
0x8000 is "SEM_NOOPENFILEERRORBOX"
0x0001 is "SEM_FAILCRITICALERRORS"

which per the documentation appear to indicate that "OpenFile" will NOT generate an error message box if it fails to find the file it opened but instead just bubble the error up to the caller.  Also it indicates that the system will not display critical error handler messages (this appears to be a best practice, so normal).


GetCommandLine windows api

Here's how I understand the GetcommandLine windows api. It takes no parameters, it simply outputs the command that was used to start this application.


The result is then that in eax (or rax in x64) that there will be a pointer to a string that shows the full command line used to launch the current application.

GetStartupInfo windows api

Here's how I understand the GetStartupInfo windows api. As a parameter it takes 1 value which is a pass by reference variable that will store the resulting output. 

The result is then that the 1 parameter gets filled with data about the current process that is running, including the workstation name and the full folder path of the executable running






Saturday, January 13, 2018

BlockInput Windows api In malware

In this hybrid analysis sample


https://www.hybrid-analysis.com/sample/775823294439f2c459d1b13dde03091ba79221d2cd9956039b47dfe51832924a?environmentId=120


It lists ability to block user input


Anti-Reverse Engineering

This is a Windows api all, so we search msdn to learn more

https://msdn.microsoft.com/en-us/library/windows/desktop/ms646290(v=vs.85).aspx



It says “keyboard and mouse input events are blocked”

So if you are a malware analyst and you let the malware run that line of code then suddenly your VMs keyboard and mouse literally won’t respond.

The good thing is it also says

The system will unblock input in the following cases: 
  • The user presses CTRL+ALT+DEL 



    Friday, September 2, 2016

    Intel Assembly Basics: Segment Registers

    Intel Assembly Basics

    6 16-bit segment registers

    1.) CS #code segment
    2.) DS #data segment
    3.) SS #stack segment
    4.) ES #extra segment
    5.) FS #general purpose segment
    6.) GS #general purpose segment


    Base address of a segment, thus accessed with offsets to an address. Example:

    mov DS:[eax], ebx


    Moves the data in ebx onto the Data Segment ... but where? The address of the data segment plus the value in eax gets you the final address.

    More about neonprimetime


    Top Blogs of all-time
    1. pagerank botnet sql injection walk-thru
    2. DOM XSS 101 Walk-Through
    3. An Invoice email and a Hot mess of Java


    Top Github Contributions
    1. Qualys Scantronitor 2.0


    Copyright © 2016, this post cannot be reproduced or retransmitted in any form without reference to the original post.

    Intel Assembly Basics: EIP Register

    Intel Assembly Basics

    EIP # instruction pointer, points to next instruction, goal of most attacks is to control this



    More about neonprimetime


    Top Blogs of all-time
    1. pagerank botnet sql injection walk-thru
    2. DOM XSS 101 Walk-Through
    3. An Invoice email and a Hot mess of Java


    Top Github Contributions
    1. Qualys Scantronitor 2.0


    Copyright © 2016, this post cannot be reproduced or retransmitted in any form without reference to the original post.

    Intel Assembly Basics: General Purpose Registers

    Intel Assembly Basics

    8 general purpose registers
    1.) EAX #can also access hi/lo order 8 bits (AH/AL)
    2.) EBX #can also access hi/lo order 8 bits (BH/BL)
    3.) ECX #used by many string instructions as a counter, can also access hi/lo order 8 bits (CH/CL)
    4.) EDX #can also access hi/lo order 8 bits (DH/DL)
    5.) ESI #used by many string instructions as a source pointer, can also access lo order 16 bits (SI)
    6.) EDI #used by many string instructions as a destination pointer, can also access lo order 16 bits (DI)
    7.) EBP #used in many stack operations, generally contain addresses, if wrong address can cause app to crash, can also access lo order 16 bits (BP)
    8.) ESP #can also access lo order 16 bits (SP)




    More about neonprimetime


    Top Blogs of all-time
    1. pagerank botnet sql injection walk-thru
    2. DOM XSS 101 Walk-Through
    3. An Invoice email and a Hot mess of Java


    Top Github Contributions
    1. Qualys Scantronitor 2.0


    Copyright © 2016, this post cannot be reproduced or retransmitted in any form without reference to the original post.

    Intel Assembly Basics: Opcode & Shell Code

    Intel Assembly Basics
    return 0;

    Could be represented by this

    leave
    xor eax, eax
    ret


    Which have lower level cpu OpCodes of these values

    leave # 0xC9
    xor eax, eax # 0x31, 0xc0
    ret # 0xC9


    Which means if you wanted to create a shellcode of the 'return 0' statement in C you'd do the following.

    unsigned char shellcode[] = "\xc9\x31\xc0\xc9";

    More about neonprimetime


    Top Blogs of all-time
    1. pagerank botnet sql injection walk-thru
    2. DOM XSS 101 Walk-Through
    3. An Invoice email and a Hot mess of Java


    Top Github Contributions
    1. Qualys Scantronitor 2.0


    Copyright © 2016, this post cannot be reproduced or retransmitted in any form without reference to the original post.

    Intel Assembly Basics: return 0;

    Intel Assembly Basics
    return 0;

    Could be represented by this

    leave # destroys the stack frame
    xor eax, eax # sets 0 to the eax register (xor is faster than setting it to 0, 1 or other not both)
    ret # returns control back to the calling program




    More about neonprimetime


    Top Blogs of all-time
    1. pagerank botnet sql injection walk-thru
    2. DOM XSS 101 Walk-Through
    3. An Invoice email and a Hot mess of Java


    Top Github Contributions
    1. Qualys Scantronitor 2.0


    Copyright © 2016, this post cannot be reproduced or retransmitted in any form without reference to the original post.

    Saturday, May 23, 2015

    gcc convert c to assembly

    Take this c program that does nothing but exit.

    #include<stdlib.h>
    void main(){
      exit(0);
    }



    Let's say you run this command to build...
      gcc -S -masm=intel -static exit.c

    Then if you view your directory you'll see you have an assembly file (exit.s)...
    ls -l
    -rw-rw-r-- 1 user user 140 May 20 12:02 exit.c
    -rw-rw-r-- 1 user user 391 May 20 12:33 exit.s


    Here is the output of the assembly file.

      .file "exit.c"
      .intel_syntax noprefix
      .text
      .globl main
      .type main, @function
    main:
    .LFB2:
      .cfi_startproc
      push ebp
      .cfi_def_cfa_offset 8
      .cfi_offset 5, -8
      mov ebp, esp
      .cfi_def_cfa_register 5
      and esp, -16
      sub esp, 16
      mov DWORD PTR [esp], 0
      call exit
      .cfi_endproc
    .LFE2:
      .size main, .-main
      .ident "GCC: (Ubuntu xxxxx) xxxxx"
      .section .note.GNU-stack,"",@progbits


    The .file tells assembly that we're starting a new file with this name.

    The .intel_syntax noprefix tells assembly we're using intel version, and we are not going to prefix registers with a % symbol

    The .text tells assembly that the code section is now starting.

    The .globl main tells assembly that main is a symbol that can be used outside this file. That is needed for the operating system to make the initial call to start this program.

    The .type main, @function is used in conjunction with the previous directive to tell the outside linker that main is a function

    The main: creates a label called main, which is what we just defined in the previous 2 directives as an externally accessible function

    The LFB2: is an auto-generated label by the compiler that likely stands for LABEL FUNCTION BEGIN #2, and is generally seen prior to every function.

    The .cfi_starproc is an auto-generated directive that the assembler will use during error handling to unwind an the stack.

    The push ebp is setting up for your function call by saving the Base Pointer on the stack so you could restore it at the end of the function (of course this isn't used/necessary in this instance since we'll never return from this function as it's calling the exit syscall).

    The .cfi_def_cfa_offset 8 is an auto-generated directive that the assembler will use during error handling to unwind an the stack.

    The .cfi_offset 5, -8 is an auto-generated directive that the assembler will use during error handling to unwind an the stack.

    The mov ebp, esp is also setting up for your function call by setting the new Base Pointer to the old Stack Pointer (basically saving off the previous stack for later use and starting a new stack for this scope).

    The .cfi_def_cfa_register 5 is an auto-generated directive that the assembler will use during error handling to unwind an the stack.

    The and esp, -16 is essentially the same as and esp, 11111111 11111111 11111111 11110000. Removing last 4 bits means rounding down to 16 byte boundary.

    The sub esp, 16 is allocating 16 bytes for local variables.

    The mov DWORD PTR [esp], 0 is saving the value 0 to the stack (basically passing 0 as a parameter to the next function).

    The call exit is the call to the syscall that exits with return code 0 (our parameter) to the operating system.

    The .cfi_endproc is an auto-generated directive that the assembler will use during error handling to unwind an the stack.

    The LFE2: is an auto-generated label by the compiler that likely stands for LABEL FUNCTION END #2, and is generally seen at the end of every function.

    The .size main, .-main tells the assembler to compute the size of symbol main to be the difference between the label main and the current position in the file

    The .ident "GCC: (Ubuntu xxxxx) xxxxx" identifies which version of the compiler generated this assembly.

    The .section .note.GNU-stack,"",@progbits is where gcc (the compiler we used) specific stack options are specified.



    Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.

    Wednesday, April 22, 2015

    The Assembly Behind MS15-034

    Recall I previously blogged about the MS15-034 DoS vulnerability that could blue screen a Windows Server with a simple HTTP request.

    Mike Czumak of securitysift.com blogged about the Assembly code behind that Http.sys vulnerability and I thought it might be interesting to attempt to explain a bit of the Assembly language code screenshot in that article.

    First here is the code from the article. If you scroll down I'll walk through it line by line.

    Unpatched
    move ecx, [esi+4]
    move eax, [esi]
    cmp edx, ecx
    jb short loc_6EEF9

    loc_6EEF9:
       sub eax, edi
       sbb ecx, edx
       add eax, 1
       adc ecx, 0
       mov [esi], eax
       move [esi+4], ecx


    Patched
    move ecx, [esi+4]
    move eax, [esi]
    cmp edx, ecx
    jb short loc_6F112

    loc_6F112:
       push esi
       push 0
       sub eax, edi
       push 1
       sbb ecx, edx
       push ecx
       push eax
       call _RtlULongLongAdd@20 ;
       test eax, eax
       jl short loc_6F184


    First, in both the patched & unpatched version there are 4 lines of code that end with a jump.

    move ecx, [esi+4]
    move eax, [esi]
    cmp edx, ecx
    jb short LABEL


    First recall that assembly used "registers" to store values for quick use. Registers like 'edi' and 'esi' are index registers used to walk yourself through the stack, arrays, as a pointer, etc. Second recall that registers like 'ecx' and 'edx' and 'eax' are general purpose registers used for doing your mathematics, comparisions, and storing temporary values, etc. Now in this case the first 2 lines are "moving values from the stack into your general purpose registers". Note that in this scenario 'eax' is the upper Range Header value in the MS15-034 vulnerablity (Recall: 18 – 18446744073709551615). In this case 'eax' would have 18446744073709551615 in it. Next is a 'cmp' operand which performs a comparison of the 2 general purpose registers. If edx < ecx then it sets the 'Carry Flag' to true. This is determining if there are any more values to check. The last line is the 'jb' (jump if below) operand which basically says that it will jump if that 'Carry Flag' is true of if edx < ecx. So it jumps to our label that contains the vulnerable code.

    loc_6EEF9:
       sub eax, edi
       sbb ecx, edx
       add eax, 1
       adc ecx, 0
       mov [esi], eax
       move [esi+4], ecx


    Now in the unpatched 6 lines of code above, it's basically subtracting your lower range header (edi or 18) from your upper range header value (eax or 18446744073709551615). It's also doing an 'sbb' or subtract with borrow on those counters so it'll know how many tests it has yet to perform. Then is does an 'add', setting eax (our upper range header value or 18446744073709551615) to eax + 1. Here in lies the problem! There is an overflow condition that can happen here. The next line of code is an 'adc' which add with carry and keeps those counters moving. Then the final 2 'mov' commands 'move the values of eax and ecx back onto the stack' (just as they were before the function started).

    loc_6F112:
       push esi
       push 0
       sub eax, edi
       push 1
       sbb ecx, edx
       push ecx
       push eax
       call _RtlULongLongAdd@20 ;
       test eax, eax
       jl short loc_6F184


    Finally let's look at the patched version. Instead of doing that eax + 1 without a check, it does the overflow check by calling the _RtlULongLongAdd function. Now you can't call a function like that without parameters. It takes 5 parameters, so you push those 5 parameters onto the stack (esi, 0, 1, ecx, and eax). Prior to that you also update those counters to keep things moving. Finally you do a 'test' combined with a 'jl' which basically checks to see if after your addition of 2 unsigned integers, did you end up with a negative number? (if so that means you overflow, if not you're good). Thus we are now patched because we're checking and handling the case where we overflow on that eax + 1.

    Hope that helps a bit, and happy patching!

    Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.