GithubHelp home page GithubHelp logo

nomade040 / nmd Goto Github PK

View Code? Open in Web Editor NEW
159.0 13.0 25.0 1.71 MB

set of single-header libraries for C/C++. The code is far from finished but some parts are quite usable.

License: The Unlicense

C++ 29.58% C 70.30% Python 0.11%
disassembler length-disassembler x86 c89 header-only single-header assembly 2d-graphics

nmd's Introduction

Build nmd_assembly.h Test nmd_assembly.h Discord Coverity Scan Build Status

nmd

set of single-header libraries for C/C++

Notable

General information

  • Each library's documentation is at the start of the file.
  • The end user should use the single-header libraries in the root directory. The code in the folders(e.g. /assembly, /graphics) is for development only.

Showcase(listed in no particular order)

Code guidelines

  • Ensure C89 compatibility.
  • Every identifier uses snake case.
  • Enums and macros are uppercase, every other identifier is lowercase.
  • Non-internal identifiers start with the NMD_ prefix. e.g. nmd_x86_decode().
  • Internal identifiers start with the _NMD_ prefix. e.g. _nmd_append_string().

Repository inspired by nothings/stb.

nmd's People

Contributors

nomade040 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nmd's Issues

Fails to decode near jump

Hi, not sure if I'm doing something wrong here, but I'm not able to decode this jump (0xff, 0x25, 0x00, 0x00, 0x00, 0x00, ....).
fail_to_disassemble

AddressSanitizer: global-buffer-overflow at nmd_assembly.h:9257 in nmd_x86_format

Hello!

With help of fuzzing I've found out that there exist unchecked op value of 0x16 in function nmd_x86_format (file nmd_assembly.h, line 9257).
_NMD_C(op) results in 6 which is not valid index for array prefixF2_mnemonics of size 3 (thus causing buffer overflow on further read of source pointer in function _nmd_append_string).

Two possible (naive?) fixes:

  1. check for op to not equal 0x16 before calling to _nmd_append_string (would break some logic?);
  2. initialize arrays like prefixF2_mnemonics with some zeroes (NULL pointers) to have size of at least 8 elements each (because op >= 0x10 && op <= 0x17) AND in function _nmd_append_string check source argument for NULL before while-loop.

Full ASAN message:

==2055366==ERROR: AddressSanitizer: global-buffer-overflow on address 0x5555557d4ef0 at pc 0x555555737e4d bp 0x7fffffffd950 sp 0x7fffffffd948
READ of size 8 at 0x5555557d4ef0 thread T0
    #0 0x555555737e4c in nmd_x86_format /home/user/git/nmd/./nmd_assembly.h:9257:29
    #1 0x55555578c74e in main /home/user/git/nmd/nmd_fuzz.c:64:13
    #2 0x7ffff7c76b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
    #3 0x55555558e28d in _start (/home/user/git/nmd/nmd_fuzz_asan+0x3a28d)

0x5555557d4ef0 is located 16 bytes to the left of global variable '__const.nmd_x86_format.no_prefix_mnemonics' defined in 'nmd_fuzz.c' (0x5555557d4f00) of size 64
0x5555557d4ef0 is located 24 bytes to the right of global variable '__const.nmd_x86_format.prefixF2_mnemonics' defined in 'nmd_fuzz.c' (0x5555557d4ec0) of size 24
SUMMARY: AddressSanitizer: global-buffer-overflow /home/user/git/nmd/./nmd_assembly.h:9257:29 in nmd_x86_format
Shadow bytes around the buggy address:
  0x0aab2aaf2980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0aab2aaf2990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0aab2aaf29a0: 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x0aab2aaf29b0: 00 00 00 00 00 00 00 00 f9 f9 f9 f9 00 00 00 f9
  0x0aab2aaf29c0: f9 f9 f9 f9 00 00 00 00 f9 f9 f9 f9 00 00 00 00
=>0x0aab2aaf29d0: 00 00 00 00 f9 f9 f9 f9 00 00 00 f9 f9 f9[f9]f9
  0x0aab2aaf29e0: 00 00 00 00 00 00 00 00 f9 f9 f9 f9 00 00 00 00
  0x0aab2aaf29f0: 00 00 00 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9
  0x0aab2aaf2a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0aab2aaf2a10: f9 f9 f9 f9 00 00 00 00 00 00 00 00 f9 f9 f9 f9
  0x0aab2aaf2a20: 00 00 00 00 00 00 00 00 f9 f9 f9 f9 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==2055366==ABORTING

To reproduce this behavior one may change buffer contents in examples/assembly_example.c to contents of this file and compile either without optimization (e.g. -O0), or with address sanitizer (-fsanitize=address). Note that I used clang to compile it.

global-buffer-overflow_nmd_assembly_h__line_9257.tar.gz

Signed integer overflow in nmd_assembly.h at lines 7715 and 7842

There are two places in nmd_assembly.h that introduce undefined behavior:

nmd_assembly.h:7715:81: runtime error: signed integer overflow: 2147483647 + 5 cannot be represented in type 'int'

relevant code part:

(int64_t)((int32_t)(si->instruction->immediate) + (int32_t)(si->instruction->length))

The field immediate is uint64_t, length is uint8_t.
Hard to understand real intention here, but my naive fix would look like this:

(int64_t)(si->instruction->immediate + si->instruction->length)

Small reproducer (contents of buffer in examples/assembly_example.c):
int_overflow_in_nmd_assembly_h__line_7715.tar.gz
(to get runtime error message, compile with clang and use flag --fsanitize=undefined)

nmd_assembly.h:7842:64: runtime error: left shift of 1 by 31 places cannot be represented in type 'int'

relevant code part:

1 << (si->instruction->disp_mask * 8 - 1)

Easily fixable by changing the first 1 to 1U:

1U << (si->instruction->disp_mask * 8 - 1)

Fails to decode vpcmov

I'm doing something that might be a bit naïve. I am trying to count each type of instruction of every 64-bit ELF binary on my system to analyze the popularity of instructions. I do this by extracting the .text section and attempting to disassemble all the instructions in them.

Several binaries provide issues such as /bin/go and /bin/john. I managed to isolate a case from the john binary that gives me trouble. Attached you can find the binary and some source code I used to isolate the issue. reproduce_issue.zip

unsigned char buffer[48] =
{
    0x4c, 0x8b, 0x95, 0x40, 0xfe, 0xff, 0xff, /* mov    r10,QWORD PTR [rbp-0x1c0] */
    0xc5, 0x29, 0xef, 0xf2,                   /* vpxor  xmm14,xmm10,xmm2 */
    0x8f, 0xe8, 0x20, 0xa2, 0xc6, 0x30,       /* vpcmov xmm0,xmm11,xmm6,xmm3 */
    0xc4, 0xc1, 0x79, 0x6f, 0x3b,             /* vmovdqa xmm7,XMMWORD PTR [r11] */
};

size_t size = sizeof(buffer);

nmd_x86_instruction instruction;
char formatted_instruction[128];

size_t i = 0;
for (; i < size; i += instruction.length)
{
    if (!nmd_x86_decode(buffer + i, size - i, &instruction, NMD_X86_MODE_64, NMD_X86_DECODER_FLAGS_ALL))
    { 
        fprintf(stderr, "\nISSUE\n\n"); 
        break;
    }

    nmd_x86_format(&instruction, formatted_instruction, NMD_X86_INVALID_RUNTIME_ADDRESS, NMD_X86_FORMAT_FLAGS_HEX);

    printf("%li\t%i %s\n", i, instruction.id, formatted_instruction);
}

Version 33ac3b62c7d1eb28ae6b71d4dd78aa133ef96488 nmd (heads/master)

(Memory) PatternScan Deadlock

When using PatternScan() in memory the threads created never finish executing, causing the executable to get stuck at thread.join();
I am using MemIn, but I would guess the same bug happens with MemEx. My compiler is VS2019.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.