79 lines
2.4 KiB
Ruby
79 lines
2.4 KiB
Ruby
|
# This file is part of Metasm, the Ruby assembly manipulation suite
|
||
|
# Copyright (C) 2007 Yoann GUILLOT
|
||
|
#
|
||
|
# Licence is LGPL, see LICENCE in the top-level directory
|
||
|
|
||
|
# this script show the assembler syntax understood by the framework
|
||
|
|
||
|
require 'metasm'
|
||
|
require 'metasm-shell'
|
||
|
|
||
|
edata = <<EOS.encode_edata
|
||
|
#line 12 // preprocessor directive (useful in case of syntax error)
|
||
|
|
||
|
// data specification
|
||
|
db 42h ; a single byte
|
||
|
db 'a' ; same thing
|
||
|
dd 0x48, 0x7, 4 dup(0x19) ; 6 double words
|
||
|
dd toto + 4*pre_pad ; data may refer to labels in arbitrary expressions
|
||
|
db "foo", 0 ; null-terminated string
|
||
|
dw "foo", 0 ; null-terminated wide string
|
||
|
dd 0b010111101100 ; binary constant
|
||
|
dd someexternalvar+12 ; an external variable to be fixed up later
|
||
|
|
||
|
// code
|
||
|
inc ebx
|
||
|
jmp toto
|
||
|
mov eax, [fs:ebx + ((kikoo<<1) - 4*lol)] ; all immediate values can be an arbitrary arithmetic/logic expression
|
||
|
push.i16 0x1234 ; specific opcode forms are defined using this kind of syntax
|
||
|
|
||
|
// labels
|
||
|
pre_pad:
|
||
|
// parser instructions
|
||
|
.pad 90h ; this statement will be replaced by the right number of 0x90 to honor the next .offset directive
|
||
|
post_pad:
|
||
|
|
||
|
toto:
|
||
|
.offset 74 + (12-48>>4)*0 ; we are now at 74 bytes from the beginning of the shellcode (db 42h)
|
||
|
; .offset accepts an arbitrary expression
|
||
|
|
||
|
.padto toto+38, db 3 dup(0b0110_0110) ; fill space with the specified data structure until 38 bytes after toto (same as .pad + .offset)
|
||
|
|
||
|
inc eax
|
||
|
|
||
|
.align 16, dw foobar + 42
|
||
|
|
||
|
local1:
|
||
|
1: // a local label (any integer allowed)
|
||
|
jmp 1b // 1b => last '1' label (same as local1)
|
||
|
jmp 1f // 1f => next '1' label (same as local2)
|
||
|
|
||
|
local2:
|
||
|
1: // local labels can be redefined as often as needed
|
||
|
mov eax, 1b // same as local2
|
||
|
|
||
|
ret
|
||
|
|
||
|
#ifdef BLABLA
|
||
|
you can also use any preprocessor directive (gcc-like syntax)
|
||
|
#pragma include_dir "/some/directory"
|
||
|
#include <foobar>
|
||
|
# elif defined(HOHOHO) && 42
|
||
|
#error 'infamous error message'
|
||
|
#else
|
||
|
#define test(ic) ((ic) - \
|
||
|
4)
|
||
|
#endif
|
||
|
|
||
|
EOS
|
||
|
|
||
|
edata.fixup 'foobar' => 1 # fixup the value of 'foobar'
|
||
|
newdata = 'somestring'
|
||
|
edata.patch 'pre_pad', 'post_pad', newdata # replace the (beginning of the) segment beetween the labels by a string
|
||
|
#edata.patch 'pre_pad', 'post_pad', 'waaaaaaaaaay tooooooooooooooooooooooooooooooooooooooooo big !!!!' # raise an error
|
||
|
|
||
|
edata.fixup 'kikoo' => 8, 'lol' => 42 # fixup the immediate values
|
||
|
edata.fixup 'someexternalvar' => 0x30303030 # fixup the external used in the data segment
|
||
|
|
||
|
p edata.data # show the resulting raw string
|