All Data Structures Files Functions Variables Enumerations Enumerator Macros Groups
bytecode_local.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009-2014 Cisco Systems, Inc.
3  * Copyright (C) 2009-2013 Sourcefire, Inc.
4  * All rights reserved.
5  * Authors: Török Edvin, Kevin Lin
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
30 #define NULL (void*)0x0
31 
32 #define force_inline inline __attribute__((always_inline))
33 #define overloadable_func __attribute__((overloadable))
34 
35 /* DOXYGEN defined() must come first */
36 #if defined(DOXYGEN) || __has_feature(attribute_overloadable)
37 /* Yes, clang supports overloading functions in C! */
45 static force_inline void overloadable_func debug(const char * str)
46 {
47  debug_print_str((const uint8_t*)str, 0);
48 }
49 
57 static force_inline void overloadable_func debug(const uint8_t* str)
58 {
59  debug_print_str((const uint8_t*)str, 0);
60 }
61 
69 static force_inline void overloadable_func debug(uint32_t a)
70 {
72 }
73 
82 void debug(...) __attribute__((overloadable, unavailable));
83 #endif
84 
85 
86 /* Virusname definition handling */
92 #define VIRUSNAME_PREFIX(name) const char __clambc_virusname_prefix[] = name;
93 
98 #define VIRUSNAMES(...) const char *const __clambc_virusnames[] = {__VA_ARGS__};
99 
100 /* Logical signature handling */
101 
102 typedef struct signature {
103  uint64_t id;
104 } __Signature;
105 
111 #define PE_UNPACKER_DECLARE const uint16_t __clambc_kind = BC_PE_UNPACKER;
112 
121 #define PDF_HOOK_DECLARE const uint16_t __clambc_kind = BC_PDF;
122 
127 #define BYTECODE_ABORT_HOOK 0xcea5e
128 
137 #define PE_HOOK_DECLARE const uint16_t __clambc_kind = BC_PE_ALL;
138 
143 #define SIGNATURES_DECL_BEGIN \
144  struct __Signatures {
145 
149 #define DECLARE_SIGNATURE(name) \
150  const char *name##_sig;\
151  __Signature name;
152 
156 #define SIGNATURES_DECL_END };
157 
163 #define TARGET(tgt) const unsigned short __Target = (tgt);
164 
170 #define COPYRIGHT(c) const char *const __Copyright = (c);
171 
177 #define ICONGROUP1(group) const char *const __IconGroup1 = (group);
178 
184 #define ICONGROUP2(group) const char *const __IconGroup2 = (group);
185 
193 #define FUNCTIONALITY_LEVEL_MIN(m) const unsigned short __FuncMin = (m);
194 
202 #define FUNCTIONALITY_LEVEL_MAX(m) const unsigned short __FuncMax = (m);
203 
204 #define LDB_ADDATTRIBUTES(x) const char * __ldb_rawattrs = (x);
205 
206 #define CONTAINER(x) const char * __ldb_container = (x);
207 
213 /* some other macro may use __COUNTER__, so we need to subtract its current\
214  * value to obtain zero-based indices */
215 #define SIGNATURES_DEF_BEGIN \
216  static const unsigned __signature_bias = __COUNTER__+1;\
217 const struct __Signatures Signatures = {\
218 
225 #define DEFINE_SIGNATURE(name, hex) \
226  .name##_sig = (hex),\
227  .name = {__COUNTER__ - __signature_bias},
228 
231 #define SIGNATURES_END };
232 
237 #define SIGNATURES_DEF_END };
238 
247 static force_inline uint32_t count_match(__Signature sig)\
248 { return __clambc_match_counts[sig.id]; }\
249 
256 static force_inline uint32_t matches(__Signature sig)\
257 { return __clambc_match_counts[sig.id] != 0; }\
258 
259 
267 static force_inline uint32_t match_location(__Signature sig, uint32_t goback)
268 {
269  int32_t pos = __clambc_match_offsets[sig.id];
271  /* bug, it returns offset of last subsig, not offset of first */
272  pos -= goback;
273  if (pos <= 0) pos = 0;
274  }
275  return pos;
276 }
277 
290 static force_inline int32_t match_location_check(__Signature sig,
291  uint32_t goback,
292  const char *static_start,
293  uint32_t static_len)
294 {
295  int32_t pos = match_location(sig, goback);
296  if (seek(pos, SEEK_SET) != pos)
297  return -1;
298  int32_t cpos = file_find_limit(static_start, static_len, pos + goback);
299  if (cpos == -1) {
300  debug("Engine reported match, but we couldn't find it! Engine reported (after fixup):");
301  debug(pos);
302  return -1;
303  }
304  if (seek(cpos, SEEK_SET) != cpos)
305  return -1;
306  if (cpos != pos && engine_functionality_level() >= FUNC_LEVEL_096_1_dev) {
307  debug("wrong match pos reported by engine, real match pos:");
308  debug(cpos);
309  debug("reported by engine:");
310  debug(pos);
311  debug("but goback fixed it up!");
312  }
313  return cpos;
314 }
315 
323 static force_inline overloadable_func void foundVirus(const char *virusname)
324 {
325  setvirusname((const uint8_t*)virusname, 0);
326 }
327 
328 #if defined(DOXYGEN) || __has_feature(attribute_overloadable)
329 
330 static force_inline void overloadable_func foundVirus(void)
331 {
332  foundVirus("");
333 }
334 #endif
335 
341 static force_inline uint32_t getFilesize(void)
342 {
343  return __clambc_filesize[0];
344 }
345 
346 union unaligned_32 {
347  uint32_t una_u32;
348  int32_t una_s32;
349 } __attribute__((packed));
350 
351 union unaligned_16 {
352  uint16_t una_u16;
353  int16_t una_s16;
354 } __attribute__((packed));
355 
372 bool __is_bigendian(void) __attribute__((const)) __attribute__((nothrow));
373 
381 static uint32_t force_inline le32_to_host(uint32_t v)
382 {
383  /* calculate bswap always, so compiler can use a select,
384  and doesn't need to create a branch.
385  This will get optimized away at bytecode load time anyway */
386  uint32_t swapped = __builtin_bswap32(v);
387  return __is_bigendian() ? swapped : v;
388 }
389 
397 static uint32_t force_inline be32_to_host(uint32_t v)
398 {
399  /* calculate bswap always, so compiler can use a select,
400  and doesn't need to create a branch.
401  This will get optimized away at bytecode load time anyway */
402  uint32_t swapped = __builtin_bswap32(v);
403  return __is_bigendian() ? v : swapped;
404 }
405 
413 static uint64_t force_inline le64_to_host(uint64_t v)
414 {
415  uint64_t swapped = __builtin_bswap64(v);
416  return __is_bigendian() ? swapped : v;
417 }
418 
426 static uint64_t force_inline be64_to_host(uint64_t v)
427 {
428  uint64_t swapped = __builtin_bswap64(v);
429  return __is_bigendian() ? v : swapped;
430 }
431 
439 static uint16_t force_inline le16_to_host(uint16_t v)
440 {
441  uint16_t swapped = ((v & 0xff) << 8) | ((v >> 8) & 0xff);
442  return __is_bigendian() ? swapped : v;
443 }
444 
452 static uint16_t force_inline be16_to_host(uint16_t v)
453 {
454  uint16_t swapped = ((v & 0xff) << 8) | ((v >> 8) & 0xff);
455  return __is_bigendian() ? v : swapped;
456 }
457 
464 static uint32_t force_inline cli_readint32(const void* buff)
465 {
466  uint32_t v = ((const union unaligned_32 *)buff)->una_s32;
467  return le32_to_host(v);
468 }
469 
476 static uint16_t force_inline cli_readint16(const void* buff)
477 {
478  uint16_t v = ((const union unaligned_16 *)buff)->una_s16;
479  return le16_to_host(v);
480 }
481 
488 static void force_inline cli_writeint32(void* offset, uint32_t v)
489 {
490  ((union unaligned_32 *)offset)->una_u32 = le32_to_host(v);
491 }
492 
493 /* --------------------- PE helper functions ------------------------ */
499 static force_inline bool hasExeInfo(void)
500 {
501  return __clambc_pedata.offset != -1;
502 }
503 
509 static force_inline bool hasPEInfo(void)
510 {
511  return (__clambc_kind == BC_PE_ALL ||
513 }
514 
515 #define NEED_PE_INFO { /* only available in PE hooks */\
516  if (!hasPEInfo())\
517  __fail_missing_PE_HOOK_DECLARE__or__PE_UNPACKER_DECLARE();\
518 }
519 
525 static force_inline bool isPE64(void)
526 {
527  NEED_PE_INFO;
528  return le16_to_host(__clambc_pedata.opt64.Magic) == 0x020b;
529 }
530 
536 static force_inline uint8_t getPEMajorLinkerVersion(void)
537 {
538  return isPE64() ?
541 }
542 
548 static force_inline uint8_t getPEMinorLinkerVersion(void)
549 {
550  return isPE64() ?
553 }
554 
560 static force_inline uint32_t getPESizeOfCode(void)
561 {
562  return le32_to_host(isPE64() ?
565 }
566 
572 static force_inline uint32_t getPESizeOfInitializedData(void)
573 {
574  return le32_to_host(isPE64() ?
577 }
578 
584 static force_inline uint32_t getPESizeOfUninitializedData(void)
585 {
586  return le32_to_host(isPE64() ?
589 }
590 
596 static force_inline uint32_t getPEBaseOfCode(void)
597 {
598  return le32_to_host(isPE64() ?
599  __clambc_pedata.opt64.BaseOfCode :
600  __clambc_pedata.opt32.BaseOfCode);
601 }
602 
608 static force_inline uint32_t getPEBaseOfData(void)
609 {
610  return le32_to_host(isPE64() ?
611  0 :
612  __clambc_pedata.opt32.BaseOfData);
613 }
614 
620 static force_inline uint64_t getPEImageBase(void)
621 {
622  return le64_to_host(isPE64() ?
625 }
626 
632 static force_inline uint32_t getPESectionAlignment(void)
633 {
634  return le32_to_host(isPE64() ?
637 }
638 
644 static force_inline uint32_t getPEFileAlignment(void)
645 {
646  return le32_to_host(isPE64() ?
649 }
650 
656 static force_inline uint16_t getPEMajorOperatingSystemVersion(void)
657 {
658  return le16_to_host(isPE64() ?
661 }
662 
668 static force_inline uint16_t getPEMinorOperatingSystemVersion(void)
669 {
670  return le16_to_host(isPE64() ?
673 }
674 
680 static force_inline uint16_t getPEMajorImageVersion(void)
681 {
682  return le16_to_host(isPE64() ?
685 }
686 
691 static force_inline uint16_t getPEMinorImageVersion(void)
692 {
693  return le16_to_host(isPE64() ?
696 }
697 
703 static force_inline uint16_t getPEMajorSubsystemVersion(void)
704 {
705  return le16_to_host(isPE64() ?
706  __clambc_pedata.opt64.MajorSubsystemVersion :
707  __clambc_pedata.opt32.MajorSubsystemVersion);
708 }
709 
715 static force_inline uint16_t getPEMinorSubsystemVersion(void)
716 {
717  return le16_to_host(isPE64() ?
718  __clambc_pedata.opt64.MinorSubsystemVersion :
719  __clambc_pedata.opt32.MinorSubsystemVersion);
720 }
721 
727 static force_inline uint32_t getPEWin32VersionValue(void)
728 {
729  return le32_to_host(isPE64() ?
730  __clambc_pedata.opt64.Win32VersionValue :
731  __clambc_pedata.opt32.Win32VersionValue);
732 }
733 
739 static force_inline uint32_t getPESizeOfImage(void)
740 {
741  return le32_to_host(isPE64() ?
742  __clambc_pedata.opt64.SizeOfImage :
743  __clambc_pedata.opt32.SizeOfImage);
744 }
745 
751 static force_inline uint32_t getPESizeOfHeaders(void)
752 {
753  return le32_to_host(isPE64() ?
754  __clambc_pedata.opt64.SizeOfHeaders :
755  __clambc_pedata.opt32.SizeOfHeaders);
756 }
757 
763 static force_inline uint32_t getPECheckSum(void)
764 {
765  return le32_to_host(isPE64() ?
768 }
769 
775 static force_inline uint16_t getPESubsystem(void)
776 {
777  return le16_to_host(isPE64() ?
778  __clambc_pedata.opt64.Subsystem :
779  __clambc_pedata.opt32.Subsystem);
780 }
781 
787 static force_inline uint16_t getPEDllCharacteristics(void)
788 {
789  return le16_to_host(isPE64() ?
790  __clambc_pedata.opt64.DllCharacteristics :
791  __clambc_pedata.opt32.DllCharacteristics);
792 }
793 
799 static force_inline uint32_t getPESizeOfStackReserve(void)
800 {
801  return le32_to_host(isPE64() ?
802  __clambc_pedata.opt64.SizeOfStackReserve :
803  __clambc_pedata.opt32.SizeOfStackReserve);
804 }
805 
811 static force_inline uint32_t getPESizeOfStackCommit(void)
812 {
813  return le32_to_host(isPE64() ?
814  __clambc_pedata.opt64.SizeOfStackCommit :
815  __clambc_pedata.opt32.SizeOfStackCommit);
816 }
817 
823 static force_inline uint32_t getPESizeOfHeapReserve(void)
824 {
825  return le32_to_host(isPE64() ?
826  __clambc_pedata.opt64.SizeOfHeapReserve :
827  __clambc_pedata.opt32.SizeOfHeapReserve);
828 }
829 
835 static force_inline uint32_t getPESizeOfHeapCommit(void)
836 {
837  return le32_to_host(isPE64() ?
838  __clambc_pedata.opt64.SizeOfHeapCommit :
839  __clambc_pedata.opt32.SizeOfHeapCommit);
840 }
841 
847 static force_inline uint32_t getPELoaderFlags(void)
848 {
849  return le32_to_host(isPE64() ?
850  __clambc_pedata.opt64.LoaderFlags :
851  __clambc_pedata.opt32.LoaderFlags);
852 }
853 
860 static force_inline uint16_t getPEMachine()
861 {
862  NEED_PE_INFO;
864 }
865 
871 static force_inline uint32_t getPETimeDateStamp()
872 {
873  NEED_PE_INFO;
875 }
876 
882 static force_inline uint32_t getPEPointerToSymbolTable()
883 {
884  NEED_PE_INFO;
886 }
887 
893 static force_inline uint32_t getPENumberOfSymbols()
894 {
895  NEED_PE_INFO;
897 }
898 
904 static force_inline uint16_t getPESizeOfOptionalHeader()
905 {
906  NEED_PE_INFO;
908 }
909 
915 static force_inline uint16_t getPECharacteristics()
916 {
917  NEED_PE_INFO;
918  return le16_to_host(__clambc_pedata.file_hdr.Characteristics);
919 }
920 
928 static force_inline bool getPEisDLL()
929 {
930  return getPECharacteristics() & 0x2000;
931 }
932 
939 static force_inline uint32_t getPEDataDirRVA(unsigned n)
940 {
941  NEED_PE_INFO;
942  struct pe_image_data_dir *p = &__clambc_pedata.opt64.DataDirectory[n];
943  struct pe_image_data_dir *p32 = &__clambc_pedata.opt32.DataDirectory[n];
944  return n < 16 ? le32_to_host(isPE64() ?
945  p->VirtualAddress :
946  p32->VirtualAddress)
947  : 0;
948 }
949 
956 static force_inline uint32_t getPEDataDirSize(unsigned n)
957 {
958  NEED_PE_INFO;
959  return n < 16 ? le32_to_host(isPE64() ?
960  __clambc_pedata.opt64.DataDirectory[n].Size :
961  __clambc_pedata.opt32.DataDirectory[n].Size)
962  : 0;
963 }
964 
970 static force_inline uint16_t getNumberOfSections(void)
971 {
972  /* available in non-PE hooks too */
973  return __clambc_pedata.nsections;
974 }
975 
981 static uint32_t getPELFANew(void)
982 {
983  NEED_PE_INFO;
985 }
986 
995 static force_inline int readPESectionName(unsigned char name[8], unsigned n)
996 {
997  NEED_PE_INFO;
998  if (n >= getNumberOfSections())
999  return -1;
1000  uint32_t at = getPELFANew() + sizeof(struct pe_image_file_hdr) + sizeof(struct pe_image_optional_hdr32);
1001  if (!isPE64()) {
1002  /* Seek to the end of the long header */
1003  at += getPESizeOfOptionalHeader() - sizeof(struct pe_image_optional_hdr32);
1004  } else {
1005  at += sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32);
1006  }
1007  at += n * sizeof(struct pe_image_section_hdr);
1008  int32_t pos = seek(at, SEEK_SET);
1009  if (pos == -1)
1010  return -2;
1011  if (read(name, 8) != 8)
1012  return -3;
1013  seek(pos, SEEK_SET);
1014  return 0;
1015 }
1016 
1022 static force_inline uint32_t getEntryPoint(void)
1023 {
1024  /* available in non-PE hooks too */
1025  return __clambc_pedata.ep;
1026 }
1027 
1033 static force_inline uint32_t getExeOffset(void)
1034 {
1035  /* available in non-PE hooks too */
1036  return __clambc_pedata.offset;
1037 }
1038 
1046 static force_inline uint32_t getImageBase(void)
1047 {
1048  NEED_PE_INFO;
1050 }
1051 
1057 static uint32_t getVirtualEntryPoint(void)
1058 {
1059  NEED_PE_INFO;
1060  return le32_to_host(isPE64() ?
1061  __clambc_pedata.opt64.AddressOfEntryPoint:
1062  __clambc_pedata.opt32.AddressOfEntryPoint);
1063 }
1064 
1071 static uint32_t getSectionRVA(unsigned i)
1072 {
1073  struct cli_exe_section section;
1074  if (get_pe_section(&section, i) == -1)
1075  return -1;
1076  return section.rva;
1077 }
1078 
1085 static uint32_t getSectionVirtualSize(unsigned i)
1086 {
1087  struct cli_exe_section section;
1088  if (get_pe_section(&section, i) == -1)
1089  return -1;
1090  return section.vsz;
1091 }
1092 
1104 static force_inline bool readRVA(uint32_t rva, void *buf, size_t bufsize)
1105 {
1106  uint32_t off = pe_rawaddr(rva);
1107  if (off == PE_INVALID_RVA)
1108  return false;
1109  int32_t oldpos = seek(off, SEEK_SET);
1110  if (oldpos == -1)
1111  return false;
1112  if (read(buf, bufsize) != bufsize) {
1113  return false;
1114  }
1115  seek(oldpos, SEEK_SET);
1116  return true;
1117 }
1118 
1119 #ifdef __cplusplus
1120 #define restrict
1121 #endif
1122 
1131 static force_inline void* memchr(const void* s, int c, size_t n)
1132 {
1133  unsigned char cc = c;
1134  const char *end, *p = s;
1135 
1136  for (end=p+n; p < end; p++)
1137  if (*p == cc)
1138  return p;
1139  return (void*)0;
1140 }
1141 
1142 /* Provided by LLVM intrinsics */
1150 void* memset(void *src, int c, uintptr_t n) __attribute__((nothrow)) __attribute__((__nonnull__((1))));
1151 
1160 void *memmove (void *dst, const void *src, uintptr_t n)
1161  __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
1162 
1171 void *memcpy (void *restrict dst, const void *restrict src, uintptr_t n)
1172  __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
1173 
1183 int memcmp (const void *s1, const void *s2, uint32_t n)
1184  __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
1185 
1190 struct DIS_mem_arg {
1191  enum DIS_SIZE access_size;
1192  enum X86REGS scale_reg;
1193  enum X86REGS add_reg;
1194  uint8_t scale;
1195  int32_t displacement;
1196 };
1197 
1202 struct DIS_arg {
1205  union {
1207  enum X86REGS reg;
1208  uint64_t other;
1209  } u;
1210 };
1211 
1216 struct DIS_fixed {
1220  uint8_t segment;
1221  struct DIS_arg arg[3];
1222 };
1223 
1232 static force_inline uint32_t
1233 DisassembleAt(struct DIS_fixed* result, uint32_t offset, uint32_t len)
1234 {
1235  struct DISASM_RESULT res;
1236  unsigned i;
1237  seek(offset, SEEK_SET);
1238  offset = disasm_x86(&res, len < sizeof(res) ? len : sizeof(res));
1239  result->x86_opcode = (enum X86OPS) cli_readint16(&res.real_op);
1240  result->operation_size = (enum DIS_SIZE) res.opsize;
1241  result->address_size = (enum DIS_SIZE) res.adsize;
1242  result->segment = res.segment;
1243  for (i=0;i<3;i++) {
1244  struct DIS_arg *arg = &result->arg[i];
1245  arg->access_type = (enum DIS_ACCESS) res.arg[i][0];
1246  switch (result->arg[i].access_type) {
1247  case ACCESS_MEM:
1248  arg->u.mem.access_size = (enum DIS_SIZE) res.arg[i][1];
1249  arg->u.mem.scale_reg = (enum X86REGS) res.arg[i][2];
1250  arg->u.mem.add_reg = (enum X86REGS) res.arg[i][3];
1251  arg->u.mem.scale = res.arg[i][4];
1252  arg->u.mem.displacement = cli_readint32((const uint32_t*)&res.arg[i][6]);
1253  break;
1254  case ACCESS_REG:
1255  arg->u.reg = (enum X86REGS) res.arg[i][1];
1256  break;
1257  default: {
1258  uint64_t x = cli_readint32((const uint32_t*)&res.arg[i][6]);
1259  arg->u.other = (x << 32) | cli_readint32((const uint32_t*)&res.arg[i][2]);
1260  break;
1261  }
1262  }
1263  }
1264  return offset;
1265 }
1266 
1267 // re2c macros
1268 #define RE2C_BSIZE 1024
1269 typedef struct {
1270  unsigned char *cur, *lim, *mrk, *ctx, *eof, *tok;
1271  int res;
1272  int32_t tokstart;
1273  unsigned char buffer[RE2C_BSIZE];
1274 } regex_scanner_t;
1275 
1276 #define YYCTYPE unsigned char
1277 #define YYCURSOR re2c_scur
1278 #define YYLIMIT re2c_slim
1279 #define YYMARKER re2c_smrk
1280 #define YYCONTEXT re2c_sctx
1281 #define YYFILL(n) { \
1282  RE2C_FILLBUFFER(n);\
1283  if (re2c_sres <= 0) break;\
1284 }
1285 
1286 #define REGEX_SCANNER unsigned char *re2c_scur, *re2c_stok, *re2c_smrk, *re2c_sctx, *re2c_slim;\
1287  int re2c_sres; int32_t re2c_stokstart;\
1288  unsigned char re2c_sbuffer[RE2C_BSIZE];\
1289  re2c_scur = re2c_slim = re2c_smrk = re2c_sctx = &re2c_sbuffer[0];\
1290  re2c_sres = 0;\
1291  RE2C_FILLBUFFER(0);
1292 
1293 #define REGEX_POS (-(re2c_slim - re2c_scur) + seek(0, SEEK_CUR))
1294 #define REGEX_LOOP_BEGIN do { re2c_stok = re2c_scur; re2c_stokstart = REGEX_POS;} while (0);
1295 #define REGEX_RESULT (re2c_sres)
1296 
1297 #define RE2C_DEBUG_PRINT \
1298 do {\
1299  char buf[81];\
1300  uint32_t here = seek(0, SEEK_CUR);\
1301  uint32_t d = re2c_slim - re2c_scur;\
1302  uint32_t end = here - d;\
1303  unsigned len = end - re2c_stokstart;\
1304  if (len > 80) {\
1305  unsigned skipped = len - 74;\
1306  seek(re2c_stokstart, SEEK_SET);\
1307  if (read(buf, 37) == 37)\
1308  break;\
1309  memcpy(buf+37, "[...]", 5);\
1310  seek(end-37, SEEK_SET);\
1311  if (read(buf, 37) != 37)\
1312  break;\
1313  buf[80] = '\0';\
1314  } else {\
1315  seek(re2c_stokstart, SEEK_SET);\
1316  if (read(buf, len) != len)\
1317  break;\
1318  buf[len] = '\0';\
1319  }\
1320  buf[80] = '\0';\
1321  debug_print_str(buf, 0);\
1322  seek(here, SEEK_SET);\
1323 } while (0)
1324 
1325 #define DEBUG_PRINT_REGEX_MATCH RE2C_DEBUG_PRINT
1326 
1327 #define BUFFER_FILL(buf, cursor, need, limit) do {\
1328  (limit) = fill_buffer((buf), sizeof((buf)), (limit), (cursor), (need));\
1329 } while (0);
1330 
1331 #define BUFFER_ENSURE(buf, cursor, need, limit) do {\
1332  if ((cursor) + (need) >= (limit)) {\
1333  BUFFER_FILL(buf, cursor, need, limit)\
1334  (cursor) = 0;\
1335  }\
1336 } while (0);
1337 
1338 /* Move stok to offset 0, and fill rest of buffer, at least with 'len' bytes.
1339  * Adjust the other pointers, which must be after the stok pointer!
1340  */
1341 #define RE2C_FILLBUFFER(need) do {\
1342  uint32_t cursor = re2c_stok - &re2c_sbuffer[0];\
1343  int32_t limit = re2c_slim - &re2c_sbuffer[0];\
1344  limit = fill_buffer(re2c_sbuffer, sizeof(re2c_sbuffer), limit, (cursor), (need));\
1345  if (!limit) {\
1346  re2c_sres = 0;\
1347  } else if (limit <= (need)) {\
1348  re2c_sres = -1;\
1349  } else {\
1350  uint32_t curoff = re2c_scur - re2c_stok;\
1351  uint32_t mrkoff = re2c_smrk - re2c_stok;\
1352  uint32_t ctxoff = re2c_sctx - re2c_stok;\
1353  re2c_slim = &re2c_sbuffer[0] + limit;\
1354  re2c_stok = &re2c_sbuffer[0];\
1355  re2c_scur = &re2c_sbuffer[0] + curoff;\
1356  re2c_smrk = &re2c_sbuffer[0] + mrkoff;\
1357  re2c_sctx = &re2c_sbuffer[0] + ctxoff;\
1358  re2c_sres = limit;\
1359  }\
1360 } while (0);
1361 
1369 static inline int32_t ilog2_compat(uint32_t a, uint32_t b)
1370 {
1371  uint32_t c = a > b ? a : b;
1372  if (c < 2048) {
1373  // scale up a,b to [0, 4096]
1374  uint32_t scale = 2048/c;
1375  a *= scale;
1376  b *= scale;
1377  } else {
1378  // scale down a,b to [0, 4096]
1379  uint32_t scale = (c+2047) / 2048;
1380  a /= scale;
1381  b /= scale;
1382  }
1383  // log(a/b) = log(a*scale/(b*scale)) = log(a*scale) - log(b*scale)
1384  return ilog_table[a] - ilog_table[b];
1385 }
static force_inline uint32_t getPECheckSum(void)
Definition: bytecode_local.h:763
DIS_SIZE
Definition: bytecode_disasm.h:334
uint32_t PointerToSymbolTable
Definition: bytecode_pe.h:41
uint32_t SectionAlignment
Definition: bytecode_pe.h:108
Definition: bytecode_api.h:253
uint16_t MajorOperatingSystemVersion
Definition: bytecode_pe.h:73
static force_inline uint32_t matches(__Signature sig)
Definition: bytecode_local.h:256
Definition: bytecode_api.h:72
Definition: bytecode_local.h:1216
static force_inline uint32_t getPESizeOfHeaders(void)
Definition: bytecode_local.h:751
uint16_t nsections
Definition: bytecode_pe.h:161
struct pe_image_optional_hdr64 opt64
Definition: bytecode_pe.h:166
uint32_t SectionAlignment
Definition: bytecode_pe.h:71
static force_inline uint16_t getPESubsystem(void)
Definition: bytecode_local.h:775
Definition: bytecode_pe.h:98
uint32_t SizeOfUninitializedData
Definition: bytecode_pe.h:104
uint16_t MinorOperatingSystemVersion
Definition: bytecode_pe.h:111
DIS_ACCESS
Definition: bytecode_disasm.h:325
static force_inline uint32_t match_location(__Signature sig, uint32_t goback)
Definition: bytecode_local.h:267
enum DIS_SIZE address_size
Definition: bytecode_local.h:1219
static force_inline uint32_t getPEBaseOfCode(void)
Definition: bytecode_local.h:596
const uint32_t __clambc_match_counts[64]
This is a low-level variable, use the Macros in bytecode_local.h instead to access it...
uint32_t rva
Definition: bytecode_execs.h:40
static force_inline uint16_t getPEMinorSubsystemVersion(void)
Definition: bytecode_local.h:715
Definition: bytecode_api.h:58
uint32_t SizeOfUninitializedData
Definition: bytecode_pe.h:66
static uint16_t force_inline cli_readint16(const void *buff)
Definition: bytecode_local.h:476
static uint16_t force_inline le16_to_host(uint16_t v)
Definition: bytecode_local.h:439
static force_inline uint16_t getPESizeOfOptionalHeader()
Definition: bytecode_local.h:904
Definition: bytecode_local.h:1202
static force_inline bool getPEisDLL()
Definition: bytecode_local.h:928
static force_inline uint32_t getPEFileAlignment(void)
Definition: bytecode_local.h:644
static uint32_t force_inline cli_readint32(const void *buff)
Definition: bytecode_local.h:464
enum X86REGS scale_reg
Definition: bytecode_local.h:1192
enum X86REGS add_reg
Definition: bytecode_local.h:1193
static force_inline bool readRVA(uint32_t rva, void *buf, size_t bufsize)
Definition: bytecode_local.h:1104
static uint32_t getVirtualEntryPoint(void)
Definition: bytecode_local.h:1057
Definition: bytecode_pe.h:36
static force_inline bool hasPEInfo(void)
Definition: bytecode_local.h:509
uint32_t NumberOfSymbols
Definition: bytecode_pe.h:42
struct pe_image_optional_hdr32 opt32
Definition: bytecode_pe.h:164
static force_inline uint32_t getPESizeOfImage(void)
Definition: bytecode_local.h:739
struct DIS_arg arg[3]
Definition: bytecode_local.h:1221
uint32_t disasm_x86(struct DISASM_RESULT *result, uint32_t len)
static force_inline uint8_t getPEMajorLinkerVersion(void)
Definition: bytecode_local.h:536
uint16_t MajorOperatingSystemVersion
Definition: bytecode_pe.h:110
static force_inline uint32_t getPESizeOfInitializedData(void)
Definition: bytecode_local.h:572
uint32_t CheckSum
Definition: bytecode_pe.h:119
uint32_t vsz
Definition: bytecode_execs.h:41
int32_t get_pe_section(struct cli_exe_section *section, uint32_t num)
static force_inline uint32_t getPESizeOfUninitializedData(void)
Definition: bytecode_local.h:584
Definition: bytecode_pe.h:135
const uint16_t __clambc_kind
Definition: bytecode_api.h:227
uint32_t ep
Definition: bytecode_pe.h:160
uint8_t MinorLinkerVersion
Definition: bytecode_pe.h:63
static force_inline uint32_t getPESizeOfHeapReserve(void)
Definition: bytecode_local.h:823
static force_inline uint32_t getEntryPoint(void)
Definition: bytecode_local.h:1022
static uint32_t getSectionVirtualSize(unsigned i)
Definition: bytecode_local.h:1085
static force_inline uint32_t getPESizeOfCode(void)
Definition: bytecode_local.h:560
static force_inline uint32_t getPESizeOfStackReserve(void)
Definition: bytecode_local.h:799
uint32_t SizeOfInitializedData
Definition: bytecode_pe.h:65
static force_inline uint32_t getPESectionAlignment(void)
Definition: bytecode_local.h:632
static uint32_t force_inline be32_to_host(uint32_t v)
Definition: bytecode_local.h:397
uint32_t CheckSum
Definition: bytecode_pe.h:82
enum DIS_SIZE operation_size
Definition: bytecode_local.h:1218
static force_inline uint16_t getPEMinorImageVersion(void)
Definition: bytecode_local.h:691
static force_inline uint16_t getPEMajorOperatingSystemVersion(void)
Definition: bytecode_local.h:656
Definition: bytecode_api.h:63
Definition: bytecode_execs.h:39
static force_inline int32_t match_location_check(__Signature sig, uint32_t goback, const char *static_start, uint32_t static_len)
Definition: bytecode_local.h:290
int32_t displacement
Definition: bytecode_local.h:1195
static force_inline uint32_t getPEWin32VersionValue(void)
Definition: bytecode_local.h:727
uint8_t MajorLinkerVersion
Definition: bytecode_pe.h:100
static uint32_t getPELFANew(void)
Definition: bytecode_local.h:981
static force_inline uint32_t getPENumberOfSymbols()
Definition: bytecode_local.h:893
static force_inline uint16_t getPEMajorSubsystemVersion(void)
Definition: bytecode_local.h:703
Definition: bytecode_pe.h:51
static force_inline uint32_t getPEDataDirSize(unsigned n)
Definition: bytecode_local.h:956
uint32_t engine_functionality_level(void)
Definition: bytecode_api.h:82
static force_inline uint32_t DisassembleAt(struct DIS_fixed *result, uint32_t offset, uint32_t len)
Definition: bytecode_local.h:1233
static force_inline overloadable_func void foundVirus(const char *virusname)
Definition: bytecode_local.h:323
enum DIS_SIZE access_size
Definition: bytecode_local.h:1191
static force_inline uint64_t getPEImageBase(void)
Definition: bytecode_local.h:620
const struct cli_pe_hook_data __clambc_pedata
void * memset(void *src, int c, uintptr_t n) __attribute__((nothrow)) __attribute__((__nonnull__((1))))
uint8_t MinorLinkerVersion
Definition: bytecode_pe.h:101
bool __is_bigendian(void) __attribute__((const )) __attribute__((nothrow))
uint32_t TimeDateStamp
Definition: bytecode_pe.h:40
static force_inline uint32_t getPELoaderFlags(void)
Definition: bytecode_local.h:847
uint64_t other
Definition: bytecode_local.h:1208
uint32_t setvirusname(const uint8_t *name, uint32_t len)
static force_inline int readPESectionName(unsigned char name[8], unsigned n)
Definition: bytecode_local.h:995
static force_inline uint32_t getPEDataDirRVA(unsigned n)
Definition: bytecode_local.h:939
int32_t read(uint8_t *data, int32_t size)
static uint32_t getSectionRVA(unsigned i)
Definition: bytecode_local.h:1071
struct DIS_mem_arg mem
Definition: bytecode_local.h:1206
static force_inline uint16_t getPEMinorOperatingSystemVersion(void)
Definition: bytecode_local.h:668
Definition: bytecode_disasm.h:329
Definition: bytecode_local.h:1190
const uint32_t __clambc_match_offsets[64]
This is a low-level variable, use the Macros in bytecode_local.h instead to access it...
enum DIS_ACCESS access_type
Definition: bytecode_local.h:1203
static force_inline uint32_t getPESizeOfHeapCommit(void)
Definition: bytecode_local.h:835
static void force_inline cli_writeint32(void *offset, uint32_t v)
Definition: bytecode_local.h:488
uint16_t MajorImageVersion
Definition: bytecode_pe.h:75
int32_t file_find_limit(const uint8_t *data, uint32_t len, int32_t maxpos)
static force_inline uint32_t count_match(__Signature sig)
Definition: bytecode_local.h:247
int32_t seek(int32_t pos, uint32_t whence)
uint16_t SizeOfOptionalHeader
Definition: bytecode_pe.h:43
Definition: bytecode_disasm.h:330
uint32_t debug_print_uint(uint32_t a)
void void * memcpy(void *restrict dst, const void *restrict src, uintptr_t n) __attribute__((__nothrow__)) __attribute__((__nonnull__(1
uint32_t pe_rawaddr(uint32_t rva)
Definition: bytecode_disasm.h:357
const uint32_t __clambc_filesize[1]
static force_inline uint32_t getPETimeDateStamp()
Definition: bytecode_local.h:871
uint16_t MinorOperatingSystemVersion
Definition: bytecode_pe.h:74
static force_inline uint16_t getPEMajorImageVersion(void)
Definition: bytecode_local.h:680
static force_inline uint32_t getImageBase(void)
Definition: bytecode_local.h:1046
static force_inline uint32_t getPEPointerToSymbolTable()
Definition: bytecode_local.h:882
X86OPS
Definition: bytecode_disasm.h:32
uint16_t MajorImageVersion
Definition: bytecode_pe.h:112
uint16_t Machine
Definition: bytecode_pe.h:38
uint8_t MajorLinkerVersion
Definition: bytecode_pe.h:62
static force_inline uint32_t getFilesize(void)
Definition: bytecode_local.h:341
uint8_t scale
Definition: bytecode_local.h:1194
uint32_t SizeOfCode
Definition: bytecode_pe.h:64
uint32_t debug_print_str(const uint8_t *str, uint32_t len)
void * memmove(void *dst, const void *src, uintptr_t n) __attribute__((__nothrow__)) __attribute__((__nonnull__(1
uint16_t MinorImageVersion
Definition: bytecode_pe.h:113
static force_inline uint32_t getPESizeOfStackCommit(void)
Definition: bytecode_local.h:811
static uint64_t force_inline be64_to_host(uint64_t v)
Definition: bytecode_local.h:426
enum X86REGS reg
Definition: bytecode_local.h:1207
static force_inline uint16_t getPEDllCharacteristics(void)
Definition: bytecode_local.h:787
static uint64_t force_inline le64_to_host(uint64_t v)
Definition: bytecode_local.h:413
static uint16_t force_inline be16_to_host(uint16_t v)
Definition: bytecode_local.h:452
static force_inline bool hasExeInfo(void)
Definition: bytecode_local.h:499
static force_inline uint32_t getPEBaseOfData(void)
Definition: bytecode_local.h:608
uint32_t FileAlignment
Definition: bytecode_pe.h:109
X86REGS
Definition: bytecode_disasm.h:345
static force_inline uint32_t getExeOffset(void)
Definition: bytecode_local.h:1033
static force_inline bool isPE64(void)
Definition: bytecode_local.h:525
struct pe_image_file_hdr file_hdr
Definition: bytecode_pe.h:163
uint32_t FileAlignment
Definition: bytecode_pe.h:72
static force_inline uint8_t getPEMinorLinkerVersion(void)
Definition: bytecode_local.h:548
static force_inline void * memchr(const void *s, int c, size_t n)
Definition: bytecode_local.h:1131
uint32_t ImageBase
Definition: bytecode_pe.h:70
static force_inline void overloadable_func debug(const char *str)
Definition: bytecode_local.h:45
uint8_t segment
Definition: bytecode_local.h:1220
enum DIS_SIZE access_size
Definition: bytecode_local.h:1204
static force_inline uint16_t getPECharacteristics()
Definition: bytecode_local.h:915
uint32_t SizeOfInitializedData
Definition: bytecode_pe.h:103
uint64_t ImageBase
Definition: bytecode_pe.h:107
static force_inline uint16_t getNumberOfSections(void)
Definition: bytecode_local.h:970
uint32_t e_lfanew
Definition: bytecode_pe.h:168
uint32_t SizeOfCode
Definition: bytecode_pe.h:102
void void int memcmp(const void *s1, const void *s2, uint32_t n) __attribute__((__nothrow__)) __attribute__((__pure__)) __attribute__((__nonnull__(1
uint16_t MinorImageVersion
Definition: bytecode_pe.h:76
static uint32_t force_inline le32_to_host(uint32_t v)
Definition: bytecode_local.h:381
enum X86OPS x86_opcode
Definition: bytecode_local.h:1217
static force_inline uint16_t getPEMachine()
Definition: bytecode_local.h:860
static int32_t ilog2_compat(uint32_t a, uint32_t b)
Definition: bytecode_local.h:1369