Coder Social home page Coder Social logo

jjyg / metasm Goto Github PK

View Code? Open in Web Editor NEW
461.0 35.0 83.0 18.23 MB

This is the main repository for metasm, a free assembler / disassembler / compiler written in ruby

Home Page: http://metasm.cr0.org/

License: GNU Lesser General Public License v2.1

Ruby 100.00%

metasm's Introduction

Metasm, the Ruby assembly manipulation suite
============================================

* sample scripts in samples/ -- read comments at the beginning of the files
* all files are licensed under the terms of the LGPL

Author: Yoann Guillot <john at ofjj.net>


Basic overview:

Metasm allows you to interact with executables formats (ExeFormat):
PE, ELF, Mach-O, Shellcode, etc.
There are three approaches to an ExeFormat:
 - compiling one up, from scratch
 - decompiling an existing format
 - manipulating the file structure


Ready-to-use scripts can be found in the samples/ subdirectory, check the
comments in the scripts headers. You can also try the --help argument if
you're feeling lucky.

For more information, check the doc/ subdirectory. The text files can be
compiled to html using the misc/txt2html.rb script.



Here is a short overview of the Metasm internals.


Assembly:

When compiling, you start from a source text (ruby String, consisting
mostly in a sequence of instructions/data/padding directive), which is parsed.

The string is handed to a Preprocessor instance (which handles #if, #ifdef,
#include, #define, /* */ etc, should be 100% compatible with gcc -E), which is
encapsulated in an AsmPreprocessor for assembler sources (to handles asm macro
definitions, 'equ' and asm ';' comments).
The interface to do that is ExeFormat#parse(text[, filename, lineno]) or
ExeFormat.assemble (which calls .new, #parse and #assemble).

The (Asm)Preprocessor returns tokens to the ExeFormat, which parses them as Data,
Padding, Labels or parser directives. Parser directives always start with a dot.
They can be generic (.pad, .offset...) or ExeFormat-specific (.section,
.import, .entrypoint...). They are handled by #parse_parser_instruction().
If the ExeFormat does not recognize a word, it is handed to its CPU instance,
which is responsible for parsing Instructions (or raise an exception).
All those tokens are stored in one or more arrays in the @source attribute of
the ExeFormat (Shellcode's @source is an Array, for PE/ELF it is a hash
[section name] => [Array of parsed data])
Every immediate value can be an arbitrary Expression (see later).

You can then assemble the source to binary sections using ExeFormat#assemble.

Once the section binaries are available, the whole binary executable can be
written to disk using ExeFormat#encode_file(filename[, format]).

PE and ELF include an autoimport feature that allows automatic creation of
import-related data for known OS-specific functions (e.g. unresolved calls to
'strcpy' will generate data so that the binary is linked against the libc
library at runtime).

The samples/{exe,pe,elf}encode.rb can take an asm source file as argument
and compile it to a working executable.

The CPU classes are responsible for parsing and encoding individual
instructions. The current Ia32 parser uses the Intel syntax (e.g. mov eax, 42).
The generic parser recognizes labels as a string at the beginning of a line
followed by a colon (e.g. 'some_label:'). GCC-style local labels may be used
(e.g. '1:', refered to using '1b' (backward) or '1f' (forward) ; may be
redefined as many times as needed.)
Data are specified using 'db'-style notation (e.g. 'dd 42h', 'db "blabla", 0')
See samples/asmsyntax.rb


EncodedData:

In Metasm all binary data is stored as an EncodedData.
EncodedData has 3 main attributes:
 - #data which holds the raw binary data (generally a ruby String, but see
VirtualString)
 - #export which is a hash associating an export name (label name) to an offset
within #data
 - #reloc which is a hash whose keys are offsets within #data, and whose values
are Relocation objects.
A Relocation object has an endianness (:little/:big), a type (:u32 for unsigned
32bits) and a target (the intended value stored here).
The target is an arbitrary arithmetic/logic Expression.

EncodedData also has a #virtsize (for e.g. .bss sections), and a #ptr (internal
offset used when decoding things)

You can fixup an EncodedData, with a Hash variable name => value (value should
be an Expression or a numeric value). When you do that, each relocation's target
is bound using the binding, and if the result is calculable (no external variable
name used in the Expression), the result is encoded using the relocation's
size/sign/endianness information. If it overflows (try to store 128 in an 8bit
signed relocation), an EncodeError exception is raised. Use the :a32 type to
allow silent overflow truncating.
If the relocation's target is not numeric, the target is unchanged if you use 
EncodedData#fixup, or it is replaced with the bound target with #fixup! .


Disassembly:

This code is found in the metasm/decode.rb source file, which defines the
Disassembler class.

The disassembler needs a decoded ExeFormat (to be able to say what data is at
which virtual address) and an entrypoint (a virtual address or export name).
It can then start to disassemble instructions. When it encounters an
Opcode marked as :setip, it asks the CPU for the jump destination (an
Expression that may involve register values, for e.g. jmp eax), and backtraces
instructions until it finds the numeric value.

On decoding, the Disassembler maintains a #decoded hash associating addresses
(expressions/integer #normalize()d) to DecodedInstructions.

The disassembly generates an InstructionBlock graph. Each block holds a list of
DecodedInstruction, and pointers to the next/previous block (by address).

The disassembler also traces data accesses by instructions, and stores Xrefs
for them.
The backtrace parameters can be tweaked, and the maximum depth to consider
can be specifically changed for :r/:w backtraces (instruction memory xrefs)
using #backtrace_maxblocks_data.
When an Expression is backtracked, each walked block is marked so that loops
are detected, and so that if a new code path is found to an existing block,
backtraces can be resumed using this new path.

The disassembler makes very few assumptions, and in particular does not
suppose that functions will return ; they will only if the backtrace of the
'ret' instructions is conclusive. This is quite powerful, but also implies
that any error in the backtracking process can lead to a full stop ; and also
means that the disassembler is quite slow.

The special method #disassemble_fast can be used to work around this when the
code is known to be well-formed (ie it assumes that all calls returns)

When a subfunction is found, a special DecodedFunction is created, which holds
a summary of the function's effects (like a DecodedInstruction on steroids).
This allows the backtracker to 'step over' subfunctions, which greatly improves
speed. The DecodedFunctions may be callback-based, to allow a very dynamic
behaviour.
External function calls create dedicated DecodedFunctions, which holds some
API information (e.g. stack fixup information, basic parameter accesses...)
This information may be derived from a C header parsed beforehand.
If no C function prototype is available, a special 'default' entry is used,
which assumes that the function has a standard ABI.

Ia32 implements a specific :default entry, which handles automatic stack fixup
resolution, by assuming that the last 'call' instruction returns. This may lead
to unexpected results ; for maximum accuracy a C header holding information for
all external functions is recommanded (see samples/factorize-headers-peimports
for a script to generate such a header from a full Visual Studio installation
and the target binary).

Ia32 also implements a specific GetProcAddress/dlsym callback, that will
yield the correct return value if the parameters can be backtraced.

The scripts implementing a full disassembler are samples/disassemble{-gui}.rb
See the comments for the GUI key bindings.


ExeFormat manipulation:

You can encode/decode an ExeFormat (ie decode sections, imports, headers etc)

Constructor: ExeFormat.decode_file(str), ExeFormat.decode_file_header(str)
Methods: ExeFormat#encode_file(filename), ExeFormat#encode_string

PE and ELF files have a LoadedPE/LoadedELF counterpart, that are able to work
with memory-mmaped versions of those formats (e.g. to debug running
processes)


VirtualString:

A VirtualString is a String-like object: you can read and may rewrite slices of
it. It can be used as EncodedData#data, and thus allows virtualization
of most Metasm algorithms.
You cannot change a VirtualString length.
Taking a slice of a VirtualString will return either a String (for small sizes)
or another VirtualString (a 'window' into the other). You can force getting a
small VirtualString using the #dup(offset, length) method.
Any unimplemented method called on it is forwarded to a frozen String which is
a full copy of the VirtualString (should be avoided if possible, the underlying
string may be very big & slow to access).

There are currently 3 VirtualStrings implemented:
- VirtualFile, whichs loads a file by page-sized chunks on demand,
- WindowsRemoteString, which maps another process' virtual memory (uses the
windows debug api through WinDbgAPI)
- LinuxRemoteString, which maps another process' virtual memory (need ptrace
rights, memory reading is done using /proc/pid/mem)

The Win/Lin version are quite powerful, and allow things like live process
disassembly/patching easily (using LoadedPE/LoadedELF as ExeFormat)


Debugging:

Metasm includes a few interfaces to handle debugging.
The WinOS and LinOS classes offer access to the underlying OS processes (e.g.
OS.current.find_process('foobar') will retrieve a running process with foobar
in its filename ; then process.mem can be used to access its memory.)

The Windows and Linux low-level debugging APIs have a basic ruby interface
(PTrace and WinAPI) ; which are used by the unified high-end Debugger class.
Remote debugging is supported through the GDB server wire protocol.

High-level debuggers can be created with the following ruby line:
Metasm::OS.current.create_debugger('foo')

Only one kind of host debugger class can exist at a time ; to debug multiple
processes, attach to other processes using the existing class. This is due
to the way the OS debugging API works on Windows and Linux.

The low-level backends are defined in the os/ subdirectory, the front-end is
defined in debug.rb.

A linux console debugging interface is available in samples/lindebug.rb ; it
uses a (simplified) SoftICE-like look and feel.
It can talk to a gdb-server socket ; use a [udp:]<host:port> target.

The disassembler-gui sample allow live process interaction when using as
target 'live:<pid or part of program name>'.


C Parser:

Metasm includes a hand-written C Parser.
It handles all the constructs i am aware of, except hex floats:
 - static const L"bla"
 - variable arguments
 - incomplete types
 - __attributes__(()), __declspec()
 - #pragma once
 - #pragma pack()
 - C99 declarators - type bla = { [ 2 ... 14 ].toto = 28 };
 - Nested functions
 - __int8 etc native types
 - Label addresses (&&label)
Also note that all those things are parsed, but most of them will fail to
compile on the Ia32/X64 backend (the only one implemented so far.)

Parsing C files should be done using an existing ExeFormat, with the
parse_c_file method. This ensures that format-specific macros/ABI are correctly
defined (ex: size of the 'long' type, ABI to pass parameters to functions, etc)

When you parse a C String using C::Parser.parse(text), you receive a Parser
object. It holds a #toplevel field, which is a C::Block, which holds #structs,
#symbols and #statements. The top-level functions are found in the #symbol hash
whose keys are the symbol names, associated to a C::Variable object holding
the functions. The function parameter/attributes are accessible through
func.type, and the code is in func.initializer, which is itself a C::Block.
Under it you'll find a tree-like structure of C::Statements (If, While, Asm,
CExpressions...)

A C::Parser may be #precompiled to transform it into a simplified version that
is easier to compile: typedefs are removed, control sequences are transformed
into 'if (XX) goto YY;' etc.

To compile a C program, use PE/ELF.compile_c, that will create a C::Parser with
exe-specific macros defined (eg __PE__ or __ELF__).

Vendor-specific headers may need to use either #pragma prepare_visualstudio
(to parse the Microsoft Visual Studio headers) or prepare_gcc (for gcc), the
latter may be auto-detected (or may not).
Vendor headers tested are VS2003 (incl. DDK) and gcc4 ; ymmv.

Currently the CPU#compilation of a C code will generate an asm source (text),
which may then be parsed & assembled to binary code.

See ExeFormat#compile_c, and samples/exeencode.rb

metasm's People

Contributors

0x00ach avatar abaniko avatar busterb avatar cbongo avatar ch1c0t avatar egypt avatar jjyg avatar jroimartin avatar kingsabri avatar stephenfewer avatar tweksteen avatar w4kfu 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

metasm's Issues

AArch64 support

It would be great to add support for Arm64 as it starts to become more popular with the recent Apple silicon etc

Assemble to invalid code

Certain magic number results to invalid code, such as
Metasm::Shellcode.assemble(Metasm::Ia32.new, 'jmp $-3000').encoded.data
results to
\xE9C\xF4\xFF\xFF
certainly it's invalid.

But this is fine
Metasm::Shellcode.assemble(Metasm::Ia32.new, 'jmp $-3100').encoded.data
=>
\xE9\xDF\xF3\xFF\xFF

What's going on?

Extract Instruction Information into Table

It would be interesting to do Linear Genetic Programming and Stochastic Machine Code Optimization with this. But I guess that a pure Ruby encoder is to slow for that.
Do you think it would it be possible to (somewhat automatically ) extract instructions and encodings into a table or spreadsheet (like e.g. https://github.com/StanfordPL/x64asm/blob/develop/src/x86.csv) ?
Then, I imagine, it would be possible to generate Ruby/C/Java code (and the necessary MRI/JRuby glue code) automatically from that table. Also, it would be a much cleaner solution IMHO.
And maybe even extract all that into a separate gem...but I'm probably dreaming...

Incorrect architecture "Needs Win32!" error

I have a .asm file that I have used the macOS peencode.rb tool on to turn it into an exe file format and when it runs it generates the exe file but also creates a file called a.out that contains:

MZ<���������������ÒÛ���� �������Needs Win32!
$��1“¥ Õ!∏�LÕ!@���PE��L�����l[��������‡���������������������������������@�������������������������à�������ß����@�����������������������������������������������������������������Ä���������������������������������������������������������������������������������������.text���à��������������������������� ��‡����������������������������������������������������������������������������������������������������������������������������������������������������������������¸Ë¶���âÂ1¿dãP0ãR ãR�ãr(�∑J&âœ1…â˘W_âœ1…â˘1ˇ¨<a|�, ¡œ
�«‚ÚRW_âœ1…â˘ãR�ãJ<ãL�x„N�—QãY �”ãI�„:Iã4ã�÷1ˇ¨¡œ
�«8‡uˆ�}¯;}$u‰XãX$�”fã KãX��”ã�ã�–âD$$[[aYZQˇ‡_âœ1…â˘_âœ1…â˘Zã�Èiˇˇˇ]h32��hws2_ThLw&�âˡ–∏ê���)ƒTPh)Äk�ˇ’j
h¿®��h���”âÊPPPP@P@PhÍ�fl‡ˇ’ój�VWhô•taˇ’Ö¿t
ˇN�uÏËg���j�j�VWh�Ÿ»_ˇ’ɯ�~6ã6j@h����Vj�hX§S¡’ìSj�VSWh�Ÿ»_ˇ’ɯ�}(Xh�@��j�Ph�/�0ˇ’WhunMaˇ’^^ˇ $�ÖpˇˇˇÈõˇˇˇ�√)∆u¡√ªµ¢Vj�Sˇ’���������������������������������������������������������������������������������������������������������������������������������������

Im assuming it has something to do with the architecture and the operating system being required to be 32bit? Also when I try to open the exe file on a windows computer it says "The version of this file is incompatible with this version of windows" I am running the latest windows 7 64 bit. I understand you can run 32bit applications of windows 64bit so I don't understand why it won't work.
Please help!
Thanks in advance.

ARM instructions not displayed correctly

Conditional suffixes and da/db/ia/ib suffixes are not in the right order for STM and LDM instructions.

For example: "\x02\x00\x2d\x58" gives "stmplda sp!, {r1}"
Expected output is: "stmdapl sp!, {r1}"

Problem seems present both when assembling and disassembling.

Missing some import function entries(compare with IDA Pro)

Hi everyone,

I use the following code to get the total number of imported functions:

require 'metasm'

i = 0
pe = Metasm::PE.decode_file("C://Windows//system32//schedsvc.dll")
pe.imports.each do |import_dir|
  i+=import_dir.imports.count
end

puts i

And the result is: 310(on my Windows 10 machine). I noticed that this is not the same as the number parsed by IDA Pro(395), with less metasm.

I'm confused, is there something wrong with my code or understanding? Thanks a lot!

Doesn't work on Ruby 1.9 32bits

Hi,

It seems that Ruby 1.9 (and likely 1.8) is broken (tested on 32bit Linux).

In particular the line:

if #{nil.object_id == 4}

in metasm/dynldr.rb results in #if true on 1.8 and 1.9 but the c parser doesn't take that, so the #define TYPE for 2.0 is used, which results in a nice heisenbug, it works (mostly) if the pointers to the object don't have 0xc at the lowest nibble.

changing it to

if #{nil.object_id == 4 ? "1" : "0"}

fixes that particular case.

Other places check RUBY_VERSION instead of nil.object_id. It can send pull, but it seems that 1.8 // 1.9 are no longer supported by Metasm?

shld and shrd instructions ia32 problem

The following code:

print Shellcode.disassemble(Ia32.new, EncodedData.new("\x66\x0F\xA4\xC2\x0A"))

give the following output:

shld ax, dx, 0ah                             ; @0  660fa4c20a

it should be "shld dx, ax, 0ah"

Same problem with the shrd instructions

NoMethodError when debugging wow64 process with ruby 64 interpreter

POC:

C:\??> type test.rb
require 'metasm'
include Metasm

def log_exception(info)
    @nb_hit = @nb_hit + 1
    if @nb_hit > 2
        @dbg.kill()
    end
end

def make_pe(sc, arch)

    bpevent = Proc.new do |dist, *args|
        info = args.first
    end
    pe = Metasm::PE.assemble(arch.new, ".entrypoint\n" + sc)
    pe.encode_file('testpe.exe')
    WinOS.get_debug_privilege()
    app = 'testpe.exe'
    @dbg = WinDebugger.new(app)
    @dbg.callback_exception = method(:log_exception)
    @nb_hit = 0
    @dbg.run_forever()
    return 0, 0
end

sc = "mov ebx, 0x%X\nmov eax, 0x%X\nadd eax, ebx\nrol ax, 0xEF\nxchg al, ah\nnop\nint 3" % [0x10, 0x12]
arch=Metasm::Ia32
expected_rax, expected_rbx = make_pe(sc, arch)

Run POC with ruby 32 bit

C:\??>C:\Ruby22\bin\ruby.exe test.rb
C:\??>

Run POC with ruby 64 bit

C:\??>C:\Ruby200-x64\bin\ruby.exe test.rb
metasm/metasm/debug.rb:1140:in `loadsyms': undefined meth
od `unpack' for nil:NilClass (NoMethodError)
        from metasm/metasm/debug.rb:157:in `block in init
ialize'
        from metasm/metasm/debug.rb:850:in `[]'
        from metasm/metasm/debug.rb:850:in `evt_loadlibra
ry'
        from metasm/metasm/os/windows.rb:1996:in `update_
dbgev'
        from metasm/metasm/os/windows.rb:2056:in `do_wait
fordebug'
        from metasm/metasm/os/windows.rb:2050:in `do_wait
_target'
        from metasm/metasm/debug.rb:913:in `wait_target'
        from metasm/metasm/debug.rb:935:in `continue_wait
'
        from metasm/metasm/debug.rb:1010:in `run_forever'

        from test.rb:29:in `make_pe'
        from test.rb:36:in `<main>'

In file metasm/os/windows.rb, in function def initialize(handle, addr_start=0, length=nil), WinOS is null:

length ||= 1 << (WinOS.open_process_handle(@handle).addrsz rescue 32)

The length will be always equal to 1 << 32.

Fix:

diff --git a/metasm/os/windows.rb b/metasm/os/windows.rb
index 08b9d0f..df0a625 100644
--- a/metasm/os/windows.rb
+++ b/metasm/os/windows.rb
@@ -1704,7 +1704,7 @@ class WindowsRemoteString < VirtualString
        # writes are done directly (if handle has appropriate privileges)
        def initialize(handle, addr_start=0, length=nil)
                @handle = handle
-               length ||= 1 << (WinOS.open_process_handle(@handle).addrsz rescue 32)
+               length ||= 1 << (Metasm::WinOS.open_process_handle(@handle).addrsz rescue 32)
                super(addr_start, length)
        end

Then WinOS.open_process_handle(@handle).addrsz returns 32 bits for a 64 bits wow process, should it be 64 ?

diff --git a/metasm/os/windows.rb b/metasm/os/windows.rb
index 08b9d0f..e911863 100644
--- a/metasm/os/windows.rb
+++ b/metasm/os/windows.rb
@@ -1238,7 +1238,7 @@ class WinOS < OS
                                byte = 0.chr*8
                                if WinAPI.iswow64process(handle, byte)
                                        if byte != 0.chr*8
-                                               32 # target = wow64
+                                               64 # target = wow64
                                        elsif WinAPI.iswow64process(WinAPI.getcurrentprocess, byte) and byte != 0.chr*8
                                                64 # us = wow64, target is not

With those 2 fix, with ruby 64 the poc run correctly:

C:\??>C:\Ruby200-x64\bin\ruby.exe test.rb
C:\??>

Unhandled Exception in Debug Event

For WinAPI::EXCEPTION_DEBUG_EVENT in update_dbgev(..), metasm must pass exception to the debugged application unless explicitly set not to.

In case the exception is not an Access violation or Breakpoint or Single Step, it is better to use DBG_EXCEPTION_NOT_HANDLED as continue code otherwise the debugged application may enter undefined state due its exception handler not getting called.

Please let me know if it makes sense.

Metasm::ParseError: invalid opcode near "svc"

not working assemble svc instruction in arm. I am sorry if it is grammatically wrong.

> Metasm::Shellcode.assemble(Metasm::ARM.new, 'svc 0')
Metasm::ParseError: invalid opcode near "svc" at "\"<unk>\"" line 1
	from /Users/takemaru/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/metasm-1.0.3/metasm/parse.rb:40:in `parse_instruction'
	from /Users/takemaru/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/metasm-1.0.3/metasm/parse.rb:330:in `parse'
	from /Users/takemaru/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/metasm-1.0.3/metasm/exe_format/shellcode.rb:69:in `assemble'
	from /Users/takemaru/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/metasm-1.0.3/metasm/exe_format/main.rb:94:in `assemble'
	from (irb):14
	from /Users/takemaru/.rbenv/versions/2.4.1/bin/irb:11:in `<main>'

metasm-shell.rb:40:in `encode': wrong number of arguments

Hey guys, I installed the latest version of metasploit from the repos without any issue, and when I try to run the metasm-shell.rb I always get the same error.

[+] Metasm assembly shell
type help for usage..

asm>
metasm-shell.rb:40:in `encode': wrong number of arguments (given 2, expected 0) (ArgumentError)
        from /opt/metasploit-framework/embedded/lib/ruby/gems/2.4.0/gems/rb-readline-0.5.5/lib/rbreadline.rb:6135:in `alloc_history_entry'
        from /opt/metasploit-framework/embedded/lib/ruby/gems/2.4.0/gems/rb-readline-0.5.5/lib/rbreadline.rb:6168:in `add_history'
        from /opt/metasploit-framework/embedded/lib/ruby/gems/2.4.0/gems/rb-readline-0.5.5/lib/readline.rb:54:in `readline'
        from metasm-shell.rb:72:in `asm'
        from metasm-shell.rb:101:in `<main>'

It doesn't matter If I run "help", an assembler line or just press enter, always the same error. Tried with the standalone version of metasm and exactly the same happens. My ruby version is
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]

install notes may be outdated

In trying to make sure I used the latest version of metasm, I followed the notes in doc/install_notes.txt and tried to clone the mercurial repo (hg clone http://metasm.cr0.org/hg/metasm/), but this gives me an HTTP 404 error. After trying a few other variations on that URL and the project website URL, I'm wondering if that document just needs to be updated to point at this github repo instead?

I'm happy to update the install notes as I go through them and submit a PR, but I just want to make sure that I'm not missing something before I take the time to make updates that are wrong/won't be accepted. I'm admittedly not very familiar with mercurial, so it's possible that I'm doing something dumb.

Wrong size while translating "int a = 0; a += func_returning_int()" to x86_64 assembler

I'm sorry but i didn't find a better title for this issue. The code that triggered the bug is this:

<<EOC

require 'metasm'

sc = Metasm::Shellcode.new(Metasm::X86_64.new)
sc.cpu.generate_PIC = true
cp = sc.cpu.new_cparser
cc = sc.cpu.new_ccompiler(cp, sc)

sc.parse <<-EOS
jmp c_func

some_func:
xor rax,rax
add rax, 29ah
ret
EOS

cp.parse <<-EOS
int some_func(void);
int c_func(void)
{
int i = 0;
i += some_func(); // THIS IS A BUG
return i;
}
EOS

asm = cc.compile

sc.parse asm
puts sc.source
sc.assemble <== ERROR

EOC

and this is what i got:

<<EOC
jmp c_func
some_func:
xor rax, rax
add rax, 29ah
ret
c_func:
push rbp
mov rbp, rsp
sub rsp, 10h
mov dword ptr [rbp-8], 0
movsxd rax, dword ptr [rbp-4]
mov [rbp-0ch], eax
inc dword ptr [rbp-4]
call some_func
add dword ptr [rbp-8], rax <== WRONG size
movsxd rax, dword ptr [rbp-8]
mov rsp, rbp
pop rbp
ret
EOC

Patch a self-extract exe / dll

Hi, I need some help by patching a self-extract exe (VB + Cobol).
I have to inject my own DLL in that process, problem is that our anti-virus scanner dont let me inject that at runtime, so I have to patch that exe. But that exe is self-extract, so then I do patch it, it remove the dll load by self.

The Exe load letter 2 own DLL's, so I had the idea to patch one of that DLL's. But there comes the next Problem, the DLL's dont know the LoadLibraryA / GetProcAddress methods.

Have you any idea to help me? Will be nice.

uninitialized constant Metasm::WinDbgAPI (NameError)

While running sample dbghelp.rb
dbghelp.rb:87:in `

': uninitialized constant Metasm::WinDbgAPI (NameError)

I havd to add $:<< "C:\Metasm" otherwise i was getting 'require' error.

Changed path of dbghelp.dll to "C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x86\dbghelp.dll"

Config:
Windows7 SP1 x64.
metasm @ C:\Metasm
ruby-1.9.3 @ C:\Ruby193

[Feature Request] Make DEFAULT_INTERP configurable from Metasm::ELF.compile_c

Sorry if this doesn't make sense. Perhaps I'm going about it the wrong way.

Using Metasm::ELF.compile_c is really convenient. It's great.

Unfortunately the interpreters are hard coded constants in metasm/exe_format/elf.rb:

        DEFAULT_INTERP = '/lib/ld-linux.so.2'
        DEFAULT_INTERP64 = '/lib64/ld-linux-x86-64.so.2'

These are incorrect for Solaris systems (tested 9, 10 and 11).

It would be great if there was an easy way to overwrite the default linker/interpreter for the generated ELF when calling Metasm::ELF.compile_c, rather than having to construct the executable from scratch, or monkey patching the library.

Executing a generated x86 ELF shared object on a Solaris system (tested on Solaris 10u11 x86) complains that ld-linux.so.2 and libc.so.6 are not present.

The shared object is valid and will run on the system, provided the right interpreter and needed libraries are available. I've verified this by making the following changes to the Solaris system:

cp /lib/ld.so.1 /lib/ld-linux.so.2
cp /lib/libc.so.1 /lib/libc.so.6

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.