Skip to content

Instantly share code, notes, and snippets.

@ivanstepanovftw
Last active September 29, 2018 07:59
Show Gist options
  • Save ivanstepanovftw/051795fa9609d06676041044156c4ebf to your computer and use it in GitHub Desktop.
Save ivanstepanovftw/051795fa9609d06676041044156c4ebf to your computer and use it in GitHub Desktop.
Address Source Line Assembly CPU Time: Total CPU Time: Self Instructions Retired: Total Instructions Retired: Self
0xa238 0 Block 1:
0xa238 245 sub %r15, %rax 0.106s 0.106s 1.9% 2,586,300,000
0xa23b 254 cmp $0x8, %rax 0.003s 0.003s 0.0% 37,000,000
0xa23f 254 jbe 0xa418 <Block 9> 0.001s 0.001s 0.0% 0
0xa245 0 Block 2:
0xa245 266 movq 0x30(%rsp), %rax 0.004s 0.004s 0.0% 44,400,000
0xa24a 266 mov $0xffffffff, %ecx 0s 0s 0.0% 11,100,000
0xa24f 266 movzxb (%rdx,%rax,1), %ebx 0.095s 0.095s 1.8% 2,430,900,000
0xa253 266 leaq 0x8(%rax), %rdi 0.005s 0.005s 0.1% 70,300,000
0xa257 266 movb %bl, 0x20(%rsp) 0s 0s 0.0% 14,800,000
0xa25b 266 vmovdqax 0x20(%rsp), %xmm2 0.005s 0.004s 0.1% 111,000,000
0xa261 266 vpinsrbb $0x1, 0x4(%rdx,%rax,1), %xmm2, %xmm0 1.676s 1.676s 24.6% 33,196,400,000
0xa269 266 vpinsrbb $0x2, 0x8(%rdx,%rax,1), %xmm0, %xmm3 0.211s 0.211s 3.7% 5,057,900,000
0xa271 255 mov $0x8, %eax 0.112s 0.112s 1.2% 1,687,200,000
0xa276 266 vmovapsx %xmm3, 0x20(%rsp) 0.001s 0s 0.0% 0
0xa27c 266 vmovdqax 0x20(%rsp), %xmm4 0.125s 0.125s 1.9% 2,578,900,000
0xa282 266 vpinsrbb $0x3, 0x4(%rdx,%rdi,1), %xmm4, %xmm0 0.330s 0.330s 1.5% 1,961,000,000
0xa28a 266 vmovapsx %xmm0, 0x20(%rsp) 0.230s 0.230s 0.0% 0
0xa290 264 cmp $0x4, %rax 0.105s 0.105s 0.0% 3,700,000
0xa294 264 jz 0xa2e0 <Block 7>
0xa296 0 Block 3:
0xa296 266 vpinsrbb $0x4, 0x8(%rdx,%rdi,1), %xmm0, %xmm0
0xa29e 266 vmovapsx %xmm0, 0x20(%rsp) 0.001s 0.001s 0.0% 0
0xa2a4 264 cmp $0x5, %rax 0.131s 0.131s 0.0% 0
0xa2a8 264 jz 0xa2e0 <Block 7>
0xa2aa 0 Block 4:
0xa2aa 266 vpinsrbb $0x5, 0xc(%rdx,%rdi,1), %xmm0, %xmm0
0xa2b2 266 vmovapsx %xmm0, 0x20(%rsp)
0xa2b8 264 cmp $0x6, %rax 0.109s 0.109s 0.0% 0
0xa2bc 264 jz 0xa2e0 <Block 7>
0xa2be 0 Block 5:
0xa2be 266 vpinsrbb $0x6, 0x10(%rdx,%rdi,1), %xmm0, %xmm0
0xa2c6 266 vmovapsx %xmm0, 0x20(%rsp)
0xa2cc 264 cmp $0x7, %rax 0.099s 0.099s 0.0% 3,700,000
0xa2d0 264 jz 0xa2e0 <Block 7>
0xa2d2 0 Block 6:
0xa2d2 266 vpinsrbb $0x7, 0x14(%rdx,%rdi,1), %xmm0, %xmm5
0xa2da 266 vmovapsx %xmm5, 0x20(%rsp) 0.001s 0.001s 0.0% 0
0xa2e0 0 Block 7:
0xa2e0 282 movq 0x30(%rsp), %rax 0.096s 0.096s 0.0% 0
0xa2e7 0 Block 8:
0xa2e7 282 andw 0x2(%rdx,%rax,1), %cx
0xa2ec 282 movw %cx, 0x28(%rsp) 0.003s 0.003s 0.0% 11,100,000
0xa418 0 Block 9:
0xa418 282 mov $0xffffffff, %ecx 0s 0s 0.0% 3,700,000
0xa41d 282 jnz 0xa5f0 <Block 13>
0xa423 0 Block 10:
0xa423 282 movq 0x30(%rsp), %rbx
0xa428 282 movzxb (%rdx,%rbx,1), %edi
0xa42c 282 movb %dil, 0x20(%rsp)
0xa431 282 vmovdqax 0x20(%rsp), %xmm6 0s 0s 0.0% 3,700,000
0xa437 282 vpinsrbb $0x1, 0x4(%rdx,%rbx,1), %xmm6, %xmm0 0.001s 0.001s 0.0% 7,400,000
0xa43f 282 vmovapsx %xmm0, 0x20(%rsp) 0s 0s 0.0% 3,700,000
0xa445 282 cmp $0x2, %rax
0xa449 282 jz 0xa2e0 <Block 7>
0xa44f 0 Block 11:
0xa44f 282 vpinsrbb $0x2, 0x8(%rdx,%rbx,1), %xmm0, %xmm7
0xa457 266 leaq 0x8(%rbx), %rdi
0xa45b 266 vmovapsx %xmm7, 0x20(%rsp)
0xa461 264 cmp $0x3, %rax
0xa465 264 jz 0xa2e0 <Block 7>
0xa46b 0 Block 12:
0xa46b 264 jmp 0xa27c
0xa5f0 0 Block 13:
0xa5f0 257 cmp $0x4, %rax 0s 0s 0.0% 3,700,000
0xa5f4 257 sbb %edi, %edi
0xa5f6 257 and $0xfed0, %di
0xa5fb 257 sub $0x2cd, %di
0xa600 257 cmp $0x4, %rax
0xa604 257 sbb %ecx, %ecx
0xa606 257 and $0xfed0, %cx
0xa60b 257 sub $0x2c1, %cx
0xa610 258 cmp $0x1, %rax
0xa614 258 jnbe 0xa423 <Block 10>
0xa61a 0 Block 14:
0xa61a 259 test %rax, %rax
0xa61d 259 jnz 0xaa96 <Block 17>
0xa623 0 Block 15:
0xa623 259 xor %ecx, %ecx
0xa625 259 jmp 0xa2e0 <Block 7>
0xa62a 0 Block 16:
0xa62a 259 nopw %ax, (%rax,%rax,1)
0xaa96 0 Block 17:
0xaa96 266 movq 0x30(%rsp), %rax
0xaa9b 266 mov %edi, %ecx 0.001s 0.001s 0.0% 0
0xaa9d 266 movzxb (%rdx,%rax,1), %eax 0s 0s 0.0% 3,700,000
0xaaa1 266 movb %al, 0x20(%rsp)
0xaaa5 266 jmp 0xa2e0 <Block 7>
0xaaaa 0 Block 18:
0xaaaa 266 leaq (,%rax,8), %rbx
0xaab2 266 jmp 0xa51f
Address Source Line Assembly CPU Time: Total CPU Time: Self Instructions Retired: Total Instructions Retired: Self
0x9e38 0 Block 1:
0x9e38 274 movq %r15, (%rsp)
0x9e3c 274 mov %r14, %r15
0x9e3f 274 nop
0xa083 0 Block 2:
0xa083 245 sub %r15, %rax 36.039ms 36.039ms 0.5% 695,600,000
0xa086 254 cmp $0x8, %rax 71.077ms 71.077ms 1.2% 1,650,200,000
0xa08a 254 jnbe 0xa320 <Block 10>
0xa090 0 Block 3:
0xa090 256 mov $0xffffffff, %ecx
0xa095 256 jnz 0xa580 <Block 14> 0ms 0ms 0.0% 3,700,000
0xa09b 0 Block 4:
0xa09b 270 movzxb (%rdi), %ebx
0xa09e 270 movb %bl, 0x4f(%rsp)
0xa0a2 271 movzxb 0x4(%rdx,%rbp,1), %ebx
0xa0a7 271 movb %bl, 0x68(%rsp)
0xa0ab 272 cmp $0x2, %rax
0xa0af 272 jz 0xa0f0
0xa0b1 0 Block 5:
0xa0b1 272 movzxb 0x8(%rdx,%rbp,1), %ebx
0xa0b6 272 movb %bl, 0x69(%rsp)
0xa0ba 273 cmp $0x3, %rax
0xa0be 273 jz 0xa0f0
0xa0c0 0 Block 6:
0xa0c0 273 movzxb 0xc(%rdx,%rbp,1), %ebx
0xa0c5 273 movb %bl, 0x6a(%rsp)
0xa0c9 274 cmp $0x4, %rax
0xa0cd 274 jz 0xa0f0
0xa0cf 0 Block 7:
0xa0cf 274 movzxb 0x10(%rdx,%rbp,1), %ebx
0xa0d4 274 leaq 0x10(%rbp), %r8
0xa0d8 274 movb %bl, 0x6b(%rsp)
0xa0dc 275 cmp $0x5, %rax
0xa0e0 275 jnz 0xa359 <Block 11>
0xa0e6 0 Block 8:
0xa0e6 275 nopw %ax, (%rax,%rax,1) 1.001ms 0ms 0.0% 0
0xa0f5 0 Block 9:
0xa0f5 282 andw 0x2(%rdi), %cx 48.052ms 48.052ms 0.9% 1,191,400,000
0xa320 0 Block 10:
0xa320 270 movzxb (%rdi), %eax 7.008ms 7.008ms 0.1% 74,000,000
0xa323 274 leaq 0x10(%rbp), %r8 19.021ms 19.021ms 0.2% 270,100,000
0xa327 270 movb %al, 0x4f(%rsp) 38.041ms 38.041ms 0.3% 440,300,000
0xa32b 271 movzxb 0x4(%rdx,%rbp,1), %eax 76.082ms 76.082ms 1.0% 1,387,500,000
0xa330 274 mov $0xffffffff, %ecx 3.003ms 3.003ms 0.1% 74,000,000
0xa335 271 movb %al, 0x68(%rsp) 9.010ms 9.010ms 0.1% 81,400,000
0xa339 272 movzxb 0x8(%rdx,%rbp,1), %eax 18.019ms 18.019ms 0.3% 399,600,000
0xa33e 272 movb %al, 0x69(%rsp) 68.074ms 68.074ms 1.1% 1,472,600,000
0xa342 273 movzxb 0xc(%rdx,%rbp,1), %eax 5.005ms 5.005ms 0.0% 55,500,000
0xa347 273 movb %al, 0x6a(%rsp) 10.011ms 10.011ms 0.1% 207,200,000
0xa34b 274 movzxb 0x10(%rdx,%rbp,1), %eax 33.036ms 33.036ms 0.4% 625,300,000
0xa350 274 movb %al, 0x6b(%rsp) 61.066ms 61.066ms 0.9% 1,313,500,000
0xa354 255 mov $0x8, %eax 3.003ms 3.003ms 0.1% 148,000,000
0xa359 0 Block 11:
0xa359 275 movzxb 0x4(%rdx,%r8,1), %ebx 12.013ms 12.013ms 0.2% 303,400,000
0xa35f 275 movb %bl, 0x6c(%rsp) 26.028ms 26.028ms 0.5% 721,500,000
0xa363 275 cmp $0x6, %rax 68.074ms 68.074ms 1.2% 1,616,900,000
0xa367 275 jz 0xa0f0
0xa36d 0 Block 12:
0xa36d 276 movzxb 0x8(%rdx,%r8,1), %ebx 5.005ms 5.005ms 0.0% 40,700,000
0xa373 276 movb %bl, 0x6d(%rsp) 13.014ms 13.014ms 0.2% 236,800,000
0xa377 276 cmp $0x8, %rax 36.039ms 36.039ms 0.5% 710,400,000
0xa37b 276 jnz 0xa0f0
0xa381 0 Block 13:
0xa381 277 movzxb 0xc(%rdx,%r8,1), %eax 55.060ms 55.060ms 0.8% 1,095,200,000
0xa387 277 movb %al, 0x6e(%rsp) 24.026ms 24.026ms 0.3% 425,500,000
0xa38b 277 jmp 0xa0f0 29.031ms 29.031ms 0.4% 532,800,000
0xa580 0 Block 14:
0xa580 277 cmp $0x3, %rax
0xa584 277 jnbe 0xaaa7 <Block 20>
0xa58a 0 Block 15:
0xa58a 277 cmp $0x1, %rax 0ms 0ms 0.0% 3,700,000
0xa58e 277 jnbe 0xaab1 <Block 21>
0xa594 0 Block 16:
0xa594 277 test %rax, %rax
0xa597 277 jnz 0xaa96 <Block 19>
0xa59d 0 Block 17:
0xa59d 277 xor %ecx, %ecx
0xa59f 277 jmp 0xa0f0
0xa5a4 0 Block 18:
0xa5a4 277 nopl %eax, (%rax)
0xaa96 0 Block 19:
0xaa96 277 movzxb (%rdi), %eax 0ms 0ms 0.0% 3,700,000
0xaa99 277 mov $0xfffffc03, %ecx
0xaa9e 277 movb %al, 0x4f(%rsp)
0xaaa2 277 jmp 0xa0f0
0xaaa7 0 Block 20:
0xaaa7 277 mov $0xfffffd3f, %ecx
0xaaac 277 jmp 0xa09b <Block 4>
0xaab1 0 Block 21:
0xaab1 277 mov $0xfffffc0f, %ecx
0xaab6 277 jmp 0xa09b <Block 4>
0xaabb 0 Block 22:
0xaabb 277 leaq (,%rax,8), %rbx
0xaac3 277 jmp 0xa517
/*
This file is part of Reverse Engine.
Array of scanner results.
Copyright (C) 2017-2018 Ivan Stepanov <[email protected]>
Copyright (C) 2015,2017 Sebastian Parschauer <[email protected]>
Copyright (C) 2017 Andrea Stacchiotti <[email protected]>
Copyright (C) 2010 WANG Lu <[email protected]>
Copyright (C) 2009 Eli Dupree <[email protected]>
This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RE_SCANNER_HH
#define RE_SCANNER_HH
#include <cinttypes>
#include <memory>
#include <cmath>
#include <chrono>
#include <fcntl.h>
#include <sys/mman.h>
#include <chrono>
#include <deque>
#include <string>
#include <boost/iostreams/device/mapped_file.hpp>
#include <stdlib.h>
//
#include "core.hh"
#include "value.hh"
#include "scanroutines.hh"
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/microsec_time_clock.hpp>
class TestTimer
{
public:
TestTimer(const std::string & name) : name(name),
start(boost::date_time::microsec_clock<boost::posix_time::ptime>::local_time())
{
}
~TestTimer()
{
using namespace std;
using namespace boost;
posix_time::ptime now(date_time::microsec_clock<posix_time::ptime>::local_time());
posix_time::time_duration d = now - start;
cout << fixed<<d.total_nanoseconds() / 1000000000.0 << " seconds "<< name << endl;
usleep(1000);
}
private:
std::string name;
boost::posix_time::ptime start;
};
namespace RE {
namespace bio = boost::iostreams;
using namespace std;
using namespace std::chrono;
class match_t {
public:
uintptr_t address;
union {
mem64_t memory;
uint8_t *bytes;
};
uint16_t flags;
explicit match_t(uintptr_t address, uint16_t userflag = flags_empty) {
this->address = address;
this->flags = userflag;
}
explicit match_t(uintptr_t address, mem64_t memory, uint16_t userflag = flags_empty) {
this->address = address;
this->memory = memory;
this->flags = userflag;
}
inline
match_flags
flag()
{
if (this->flags & RE::flag_i64) return RE::flag_i64;
else if (this->flags & RE::flag_i32) return RE::flag_i32;
else if (this->flags & RE::flag_i16) return RE::flag_i16;
else if (this->flags & RE::flag_i8) return RE::flag_i8;
else if (this->flags & RE::flag_u64) return RE::flag_u64;
else if (this->flags & RE::flag_u32) return RE::flag_u32;
else if (this->flags & RE::flag_u16) return RE::flag_u16;
else if (this->flags & RE::flag_u8) return RE::flag_u8;
else if (this->flags & RE::flag_f64) return RE::flag_f64;
else if (this->flags & RE::flag_f32) return RE::flag_f32;
}
inline
std::string
flag2str()
{
if (this->flags & RE::flag_i64) return "i64";
else if (this->flags & RE::flag_i32) return "i32";
else if (this->flags & RE::flag_i16) return "i16";
else if (this->flags & RE::flag_i8) return "i8";
else if (this->flags & RE::flag_u64) return "u64";
else if (this->flags & RE::flag_u32) return "u32";
else if (this->flags & RE::flag_u16) return "u16";
else if (this->flags & RE::flag_u8) return "u8";
else if (this->flags & RE::flag_f64) return "f64";
else if (this->flags & RE::flag_f32) return "f32";
}
inline
std::string
val2str()
{
if (this->flags & RE::flag_i64) return std::to_string(this->memory.i64);
else if (this->flags & RE::flag_i32) return std::to_string(this->memory.i32);
else if (this->flags & RE::flag_i16) return std::to_string(this->memory.i16);
else if (this->flags & RE::flag_i8) return std::to_string(this->memory.i8);
else if (this->flags & RE::flag_u64) return std::to_string(this->memory.u64);
else if (this->flags & RE::flag_u32) return std::to_string(this->memory.u32);
else if (this->flags & RE::flag_u16) return std::to_string(this->memory.u16);
else if (this->flags & RE::flag_u8) return std::to_string(this->memory.u8);
else if (this->flags & RE::flag_f64) return std::to_string(this->memory.f64);
else if (this->flags & RE::flag_f32) return std::to_string(this->memory.f32);
}
inline
std::string
address2str()
{
char *address_string;
const uint8_t *b = reinterpret_cast<const uint8_t *>(&this->address);
asprintf(&address_string, /*0x*/"%02x%02x%02x%02x%02x%02x", b[5], b[4], b[3], b[2], b[1], b[0]);
return string(address_string);
}
};
/* Single match struct */
//#pragma pack(push, 1)
struct byte_with_flags {
uint8_t byte;
match_flags flags;
};
//#pragma pack(pop)
class swath_t
{
public:
uintptr_t base_address;
// fixme[low]: slow, because 'new' calls constructor and copies data
std::vector<byte_with_flags> data;
explicit swath_t(uintptr_t base_address) {
this->base_address = base_address;
}
uintptr_t
remote_get(size_t n) {
return base_address + static_cast<uintptr_t>(n);
}
uintptr_t
remote_back() {
return remote_get(data.size() - 1);
}
/* for printable text representation */
inline
void data_to_printable_string(char *buf,
int buf_length,
size_t index,
int string_length)
{
long swath_length = this->data.size() - index;
/* TODO: what if length is too large ? */
long max_length = (swath_length >= string_length) ? string_length : swath_length;
int i;
for(i = 0; i < max_length; i++) {
uint8_t byte = this->data[index + i].byte;
buf[i] = isprint(byte) ? byte : '.';
}
buf[i] = 0; /* null-terminate */
}
/* for bytearray representation */
inline
void data_to_bytearray_text(char *buf,
int buf_length,
size_t index,
int bytearray_length)
{
int i;
int bytes_used = 0;
long swath_length = this->data.size() - index;
/* TODO: what if length is too large ? */
long max_length = (swath_length >= bytearray_length) ?
bytearray_length : swath_length;
for(i = 0; i < max_length; i++) {
uint8_t byte = this->data[index + i].byte;
/* TODO: check error here */
snprintf(buf + bytes_used, buf_length - bytes_used,
(i < max_length - 1) ? "%02x " : "%02x", byte);
bytes_used += 3;
}
}
/* only at most sizeof(int64_t) bytes will be read,
if more bytes are needed (e.g. bytearray),
read them separately (for performance) */
[[gnu::always_inline]]
value_t
inline __attribute__((always_inline))
data_to_val_aux(size_t index, size_t swath_length)
{
value_t val;
size_t max_bytes = swath_length - index;
/* Init all possible flags in a single go.
* Also init length to the maximum possible value */
val.flags = flags_max;
/* NOTE: This does the right thing for VLT because the flags are in
* the same order as the number representation (for both endians), so
* that the zeroing of a flag does not change useful bits of `length`. */
if (max_bytes > 8)
max_bytes = 8;
if (max_bytes < 8) val.flags &= ~flags_64b;
if (max_bytes < 4) val.flags &= ~flags_32b;
if (max_bytes < 2) val.flags &= ~flags_16b;
if (max_bytes < 1) val.flags = flags_empty;
/* Unrolling this will improve performance by 40% for gcc. icc is not affected.
* TODO to investigate */
#ifdef loop_
for(size_t i = 0; i < max_bytes; i++) {
/* Both uint8_t, no explicit casting needed */
val.bytes[i] = data[index + i].byte;
}
#endif
#ifdef unrolled_
if LIKELY(max_bytes > 0) { val.bytes[0] = data[index + 0].byte;
if LIKELY(max_bytes > 1) { val.bytes[1] = data[index + 1].byte;
if LIKELY(max_bytes > 2) { val.bytes[2] = data[index + 2].byte;
if LIKELY(max_bytes > 3) { val.bytes[3] = data[index + 3].byte;
if LIKELY(max_bytes > 4) { val.bytes[4] = data[index + 4].byte;
if LIKELY(max_bytes > 5) { val.bytes[5] = data[index + 5].byte;
if LIKELY(max_bytes > 6) { val.bytes[6] = data[index + 6].byte;
if LIKELY(max_bytes > 7) { val.bytes[7] = data[index + 7].byte;
}}}}}}}}
#endif
/* Truncate to the old flags, which are stored with the first matched byte */
val.flags &= data[index].flags;
return val;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment