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 
145 #define PRECLASS_HOOK_DECLARE const uint16_t __clambc_kind = BC_PRECLASS;
146 
151 #define SIGNATURES_DECL_BEGIN \
152  struct __Signatures {
153 
157 #define DECLARE_SIGNATURE(name) \
158  const char *name##_sig;\
159  __Signature name;
160 
164 #define SIGNATURES_DECL_END };
165 
171 #define TARGET(tgt) const unsigned short __Target = (tgt);
172 
178 #define COPYRIGHT(c) const char *const __Copyright = (c);
179 
185 #define ICONGROUP1(group) const char *const __IconGroup1 = (group);
186 
192 #define ICONGROUP2(group) const char *const __IconGroup2 = (group);
193 
201 #define FUNCTIONALITY_LEVEL_MIN(m) const unsigned short __FuncMin = (m);
202 
210 #define FUNCTIONALITY_LEVEL_MAX(m) const unsigned short __FuncMax = (m);
211 
212 #define LDB_ADDATTRIBUTES(x) const char * __ldb_rawattrs = (x);
213 
214 #define CONTAINER(x) const char * __ldb_container = (x);
215 
221 /* some other macro may use __COUNTER__, so we need to subtract its current\
222  * value to obtain zero-based indices */
223 #define SIGNATURES_DEF_BEGIN \
224  static const unsigned __signature_bias = __COUNTER__+1;\
225 const struct __Signatures Signatures = {\
226 
233 #define DEFINE_SIGNATURE(name, hex) \
234  .name##_sig = (hex),\
235  .name = {__COUNTER__ - __signature_bias},
236 
239 #define SIGNATURES_END };
240 
245 #define SIGNATURES_DEF_END };
246 
255 static force_inline uint32_t count_match(__Signature sig)\
256 { return __clambc_match_counts[sig.id]; }\
257 
264 static force_inline uint32_t matches(__Signature sig)\
265 { return __clambc_match_counts[sig.id] != 0; }\
266 
267 
275 static force_inline uint32_t match_location(__Signature sig, uint32_t goback)
276 {
277  int32_t pos = __clambc_match_offsets[sig.id];
279  /* bug, it returns offset of last subsig, not offset of first */
280  pos -= goback;
281  if (pos <= 0) pos = 0;
282  }
283  return pos;
284 }
285 
298 static force_inline int32_t match_location_check(__Signature sig,
299  uint32_t goback,
300  const char *static_start,
301  uint32_t static_len)
302 {
303  int32_t pos = match_location(sig, goback);
304  if (seek(pos, SEEK_SET) != pos)
305  return -1;
306  int32_t cpos = file_find_limit(static_start, static_len, pos + goback);
307  if (cpos == -1) {
308  debug("Engine reported match, but we couldn't find it! Engine reported (after fixup):");
309  debug(pos);
310  return -1;
311  }
312  if (seek(cpos, SEEK_SET) != cpos)
313  return -1;
314  if (cpos != pos && engine_functionality_level() >= FUNC_LEVEL_096_1_dev) {
315  debug("wrong match pos reported by engine, real match pos:");
316  debug(cpos);
317  debug("reported by engine:");
318  debug(pos);
319  debug("but goback fixed it up!");
320  }
321  return cpos;
322 }
323 
331 static force_inline overloadable_func void foundVirus(const char *virusname)
332 {
333  setvirusname((const uint8_t*)virusname, 0);
334 }
335 
336 #if defined(DOXYGEN) || __has_feature(attribute_overloadable)
337 
338 static force_inline void overloadable_func foundVirus(void)
339 {
340  foundVirus("");
341 }
342 #endif
343 
349 static force_inline uint32_t getFilesize(void)
350 {
351  return __clambc_filesize[0];
352 }
353 
354 union unaligned_32 {
355  uint32_t una_u32;
356  int32_t una_s32;
357 } __attribute__((packed));
358 
359 union unaligned_16 {
360  uint16_t una_u16;
361  int16_t una_s16;
362 } __attribute__((packed));
363 
380 bool __is_bigendian(void) __attribute__((const)) __attribute__((nothrow));
381 
389 static uint32_t force_inline le32_to_host(uint32_t v)
390 {
391  /* calculate bswap always, so compiler can use a select,
392  and doesn't need to create a branch.
393  This will get optimized away at bytecode load time anyway */
394  uint32_t swapped = __builtin_bswap32(v);
395  return __is_bigendian() ? swapped : v;
396 }
397 
405 static uint32_t force_inline be32_to_host(uint32_t v)
406 {
407  /* calculate bswap always, so compiler can use a select,
408  and doesn't need to create a branch.
409  This will get optimized away at bytecode load time anyway */
410  uint32_t swapped = __builtin_bswap32(v);
411  return __is_bigendian() ? v : swapped;
412 }
413 
421 static uint64_t force_inline le64_to_host(uint64_t v)
422 {
423  uint64_t swapped = __builtin_bswap64(v);
424  return __is_bigendian() ? swapped : v;
425 }
426 
434 static uint64_t force_inline be64_to_host(uint64_t v)
435 {
436  uint64_t swapped = __builtin_bswap64(v);
437  return __is_bigendian() ? v : swapped;
438 }
439 
447 static uint16_t force_inline le16_to_host(uint16_t v)
448 {
449  uint16_t swapped = ((v & 0xff) << 8) | ((v >> 8) & 0xff);
450  return __is_bigendian() ? swapped : v;
451 }
452 
460 static uint16_t force_inline be16_to_host(uint16_t v)
461 {
462  uint16_t swapped = ((v & 0xff) << 8) | ((v >> 8) & 0xff);
463  return __is_bigendian() ? v : swapped;
464 }
465 
472 static uint32_t force_inline cli_readint32(const void* buff)
473 {
474  uint32_t v = ((const union unaligned_32 *)buff)->una_s32;
475  return le32_to_host(v);
476 }
477 
484 static uint16_t force_inline cli_readint16(const void* buff)
485 {
486  uint16_t v = ((const union unaligned_16 *)buff)->una_s16;
487  return le16_to_host(v);
488 }
489 
496 static void force_inline cli_writeint32(void* offset, uint32_t v)
497 {
498  ((union unaligned_32 *)offset)->una_u32 = le32_to_host(v);
499 }
500 
501 /* --------------------- PE helper functions ------------------------ */
507 static force_inline bool hasExeInfo(void)
508 {
509  return __clambc_pedata.offset != -1;
510 }
511 
517 static force_inline bool hasPEInfo(void)
518 {
519  return (__clambc_kind == BC_PE_ALL ||
521 }
522 
523 #define NEED_PE_INFO { /* only available in PE hooks */\
524  if (!hasPEInfo())\
525  __fail_missing_PE_HOOK_DECLARE__or__PE_UNPACKER_DECLARE();\
526 }
527 
533 static force_inline bool isPE64(void)
534 {
535  NEED_PE_INFO;
536  return le16_to_host(__clambc_pedata.opt64.Magic) == 0x020b;
537 }
538 
544 static force_inline uint8_t getPEMajorLinkerVersion(void)
545 {
546  return isPE64() ?
549 }
550 
556 static force_inline uint8_t getPEMinorLinkerVersion(void)
557 {
558  return isPE64() ?
561 }
562 
568 static force_inline uint32_t getPESizeOfCode(void)
569 {
570  return le32_to_host(isPE64() ?
573 }
574 
580 static force_inline uint32_t getPESizeOfInitializedData(void)
581 {
582  return le32_to_host(isPE64() ?
585 }
586 
592 static force_inline uint32_t getPESizeOfUninitializedData(void)
593 {
594  return le32_to_host(isPE64() ?
597 }
598 
604 static force_inline uint32_t getPEBaseOfCode(void)
605 {
606  return le32_to_host(isPE64() ?
607  __clambc_pedata.opt64.BaseOfCode :
608  __clambc_pedata.opt32.BaseOfCode);
609 }
610 
616 static force_inline uint32_t getPEBaseOfData(void)
617 {
618  return le32_to_host(isPE64() ?
619  0 :
620  __clambc_pedata.opt32.BaseOfData);
621 }
622 
628 static force_inline uint64_t getPEImageBase(void)
629 {
630  return le64_to_host(isPE64() ?
633 }
634 
640 static force_inline uint32_t getPESectionAlignment(void)
641 {
642  return le32_to_host(isPE64() ?
645 }
646 
652 static force_inline uint32_t getPEFileAlignment(void)
653 {
654  return le32_to_host(isPE64() ?
657 }
658 
664 static force_inline uint16_t getPEMajorOperatingSystemVersion(void)
665 {
666  return le16_to_host(isPE64() ?
669 }
670 
676 static force_inline uint16_t getPEMinorOperatingSystemVersion(void)
677 {
678  return le16_to_host(isPE64() ?
681 }
682 
688 static force_inline uint16_t getPEMajorImageVersion(void)
689 {
690  return le16_to_host(isPE64() ?
693 }
694 
699 static force_inline uint16_t getPEMinorImageVersion(void)
700 {
701  return le16_to_host(isPE64() ?
704 }
705 
711 static force_inline uint16_t getPEMajorSubsystemVersion(void)
712 {
713  return le16_to_host(isPE64() ?
714  __clambc_pedata.opt64.MajorSubsystemVersion :
715  __clambc_pedata.opt32.MajorSubsystemVersion);
716 }
717 
723 static force_inline uint16_t getPEMinorSubsystemVersion(void)
724 {
725  return le16_to_host(isPE64() ?
726  __clambc_pedata.opt64.MinorSubsystemVersion :
727  __clambc_pedata.opt32.MinorSubsystemVersion);
728 }
729 
735 static force_inline uint32_t getPEWin32VersionValue(void)
736 {
737  return le32_to_host(isPE64() ?
738  __clambc_pedata.opt64.Win32VersionValue :
739  __clambc_pedata.opt32.Win32VersionValue);
740 }
741 
747 static force_inline uint32_t getPESizeOfImage(void)
748 {
749  return le32_to_host(isPE64() ?
750  __clambc_pedata.opt64.SizeOfImage :
751  __clambc_pedata.opt32.SizeOfImage);
752 }
753 
759 static force_inline uint32_t getPESizeOfHeaders(void)
760 {
761  return le32_to_host(isPE64() ?
762  __clambc_pedata.opt64.SizeOfHeaders :
763  __clambc_pedata.opt32.SizeOfHeaders);
764 }
765 
771 static force_inline uint32_t getPECheckSum(void)
772 {
773  return le32_to_host(isPE64() ?
776 }
777 
783 static force_inline uint16_t getPESubsystem(void)
784 {
785  return le16_to_host(isPE64() ?
786  __clambc_pedata.opt64.Subsystem :
787  __clambc_pedata.opt32.Subsystem);
788 }
789 
795 static force_inline uint16_t getPEDllCharacteristics(void)
796 {
797  return le16_to_host(isPE64() ?
798  __clambc_pedata.opt64.DllCharacteristics :
799  __clambc_pedata.opt32.DllCharacteristics);
800 }
801 
807 static force_inline uint32_t getPESizeOfStackReserve(void)
808 {
809  return le32_to_host(isPE64() ?
810  __clambc_pedata.opt64.SizeOfStackReserve :
811  __clambc_pedata.opt32.SizeOfStackReserve);
812 }
813 
819 static force_inline uint32_t getPESizeOfStackCommit(void)
820 {
821  return le32_to_host(isPE64() ?
822  __clambc_pedata.opt64.SizeOfStackCommit :
823  __clambc_pedata.opt32.SizeOfStackCommit);
824 }
825 
831 static force_inline uint32_t getPESizeOfHeapReserve(void)
832 {
833  return le32_to_host(isPE64() ?
834  __clambc_pedata.opt64.SizeOfHeapReserve :
835  __clambc_pedata.opt32.SizeOfHeapReserve);
836 }
837 
843 static force_inline uint32_t getPESizeOfHeapCommit(void)
844 {
845  return le32_to_host(isPE64() ?
846  __clambc_pedata.opt64.SizeOfHeapCommit :
847  __clambc_pedata.opt32.SizeOfHeapCommit);
848 }
849 
855 static force_inline uint32_t getPELoaderFlags(void)
856 {
857  return le32_to_host(isPE64() ?
858  __clambc_pedata.opt64.LoaderFlags :
859  __clambc_pedata.opt32.LoaderFlags);
860 }
861 
868 static force_inline uint16_t getPEMachine()
869 {
870  NEED_PE_INFO;
872 }
873 
879 static force_inline uint32_t getPETimeDateStamp()
880 {
881  NEED_PE_INFO;
883 }
884 
890 static force_inline uint32_t getPEPointerToSymbolTable()
891 {
892  NEED_PE_INFO;
894 }
895 
901 static force_inline uint32_t getPENumberOfSymbols()
902 {
903  NEED_PE_INFO;
905 }
906 
912 static force_inline uint16_t getPESizeOfOptionalHeader()
913 {
914  NEED_PE_INFO;
916 }
917 
923 static force_inline uint16_t getPECharacteristics()
924 {
925  NEED_PE_INFO;
926  return le16_to_host(__clambc_pedata.file_hdr.Characteristics);
927 }
928 
936 static force_inline bool getPEisDLL()
937 {
938  return getPECharacteristics() & 0x2000;
939 }
940 
947 static force_inline uint32_t getPEDataDirRVA(unsigned n)
948 {
949  NEED_PE_INFO;
950  struct pe_image_data_dir *p = &__clambc_pedata.opt64.DataDirectory[n];
951  struct pe_image_data_dir *p32 = &__clambc_pedata.opt32.DataDirectory[n];
952  return n < 16 ? le32_to_host(isPE64() ?
953  p->VirtualAddress :
954  p32->VirtualAddress)
955  : 0;
956 }
957 
964 static force_inline uint32_t getPEDataDirSize(unsigned n)
965 {
966  NEED_PE_INFO;
967  return n < 16 ? le32_to_host(isPE64() ?
968  __clambc_pedata.opt64.DataDirectory[n].Size :
969  __clambc_pedata.opt32.DataDirectory[n].Size)
970  : 0;
971 }
972 
978 static force_inline uint16_t getNumberOfSections(void)
979 {
980  /* available in non-PE hooks too */
981  return __clambc_pedata.nsections;
982 }
983 
989 static uint32_t getPELFANew(void)
990 {
991  NEED_PE_INFO;
993 }
994 
1003 static force_inline int readPESectionName(unsigned char name[8], unsigned n)
1004 {
1005  NEED_PE_INFO;
1006  if (n >= getNumberOfSections())
1007  return -1;
1008  uint32_t at = getPELFANew() + sizeof(struct pe_image_file_hdr) + sizeof(struct pe_image_optional_hdr32);
1009  if (!isPE64()) {
1010  /* Seek to the end of the long header */
1011  at += getPESizeOfOptionalHeader() - sizeof(struct pe_image_optional_hdr32);
1012  } else {
1013  at += sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32);
1014  }
1015  at += n * sizeof(struct pe_image_section_hdr);
1016  int32_t pos = seek(at, SEEK_SET);
1017  if (pos == -1)
1018  return -2;
1019  if (read(name, 8) != 8)
1020  return -3;
1021  seek(pos, SEEK_SET);
1022  return 0;
1023 }
1024 
1030 static force_inline uint32_t getEntryPoint(void)
1031 {
1032  /* available in non-PE hooks too */
1033  return __clambc_pedata.ep;
1034 }
1035 
1041 static force_inline uint32_t getExeOffset(void)
1042 {
1043  /* available in non-PE hooks too */
1044  return __clambc_pedata.offset;
1045 }
1046 
1054 static force_inline uint32_t getImageBase(void)
1055 {
1056  NEED_PE_INFO;
1058 }
1059 
1065 static uint32_t getVirtualEntryPoint(void)
1066 {
1067  NEED_PE_INFO;
1068  return le32_to_host(isPE64() ?
1069  __clambc_pedata.opt64.AddressOfEntryPoint:
1070  __clambc_pedata.opt32.AddressOfEntryPoint);
1071 }
1072 
1079 static uint32_t getSectionRVA(unsigned i)
1080 {
1081  struct cli_exe_section section;
1082  if (get_pe_section(&section, i) == -1)
1083  return -1;
1084  return section.rva;
1085 }
1086 
1093 static uint32_t getSectionVirtualSize(unsigned i)
1094 {
1095  struct cli_exe_section section;
1096  if (get_pe_section(&section, i) == -1)
1097  return -1;
1098  return section.vsz;
1099 }
1100 
1112 static force_inline bool readRVA(uint32_t rva, void *buf, size_t bufsize)
1113 {
1114  uint32_t off = pe_rawaddr(rva);
1115  if (off == PE_INVALID_RVA)
1116  return false;
1117  int32_t oldpos = seek(off, SEEK_SET);
1118  if (oldpos == -1)
1119  return false;
1120  if (read(buf, bufsize) != bufsize) {
1121  return false;
1122  }
1123  seek(oldpos, SEEK_SET);
1124  return true;
1125 }
1126 
1127 #ifdef __cplusplus
1128 #define restrict
1129 #endif
1130 
1139 static force_inline void* memchr(const void* s, int c, size_t n)
1140 {
1141  unsigned char cc = c;
1142  const char *end, *p = s;
1143 
1144  for (end=p+n; p < end; p++)
1145  if (*p == cc)
1146  return p;
1147  return (void*)0;
1148 }
1149 
1150 /* Provided by LLVM intrinsics */
1158 void* memset(void *src, int c, uintptr_t n) __attribute__((nothrow)) __attribute__((__nonnull__((1))));
1159 
1168 void *memmove (void *dst, const void *src, uintptr_t n)
1169  __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
1170 
1179 void *memcpy (void *restrict dst, const void *restrict src, uintptr_t n)
1180  __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
1181 
1191 int memcmp (const void *s1, const void *s2, uint32_t n)
1192  __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
1193 
1198 struct DIS_mem_arg {
1199  enum DIS_SIZE access_size;
1200  enum X86REGS scale_reg;
1201  enum X86REGS add_reg;
1202  uint8_t scale;
1203  int32_t displacement;
1204 };
1205 
1210 struct DIS_arg {
1213  union {
1215  enum X86REGS reg;
1216  uint64_t other;
1217  } u;
1218 };
1219 
1224 struct DIS_fixed {
1228  uint8_t segment;
1229  struct DIS_arg arg[3];
1230 };
1231 
1240 static force_inline uint32_t
1241 DisassembleAt(struct DIS_fixed* result, uint32_t offset, uint32_t len)
1242 {
1243  struct DISASM_RESULT res;
1244  unsigned i;
1245  seek(offset, SEEK_SET);
1246  offset = disasm_x86(&res, len < sizeof(res) ? len : sizeof(res));
1247  result->x86_opcode = (enum X86OPS) cli_readint16(&res.real_op);
1248  result->operation_size = (enum DIS_SIZE) res.opsize;
1249  result->address_size = (enum DIS_SIZE) res.adsize;
1250  result->segment = res.segment;
1251  for (i=0;i<3;i++) {
1252  struct DIS_arg *arg = &result->arg[i];
1253  arg->access_type = (enum DIS_ACCESS) res.arg[i][0];
1254  switch (result->arg[i].access_type) {
1255  case ACCESS_MEM:
1256  arg->u.mem.access_size = (enum DIS_SIZE) res.arg[i][1];
1257  arg->u.mem.scale_reg = (enum X86REGS) res.arg[i][2];
1258  arg->u.mem.add_reg = (enum X86REGS) res.arg[i][3];
1259  arg->u.mem.scale = res.arg[i][4];
1260  arg->u.mem.displacement = cli_readint32((const uint32_t*)&res.arg[i][6]);
1261  break;
1262  case ACCESS_REG:
1263  arg->u.reg = (enum X86REGS) res.arg[i][1];
1264  break;
1265  default: {
1266  uint64_t x = cli_readint32((const uint32_t*)&res.arg[i][6]);
1267  arg->u.other = (x << 32) | cli_readint32((const uint32_t*)&res.arg[i][2]);
1268  break;
1269  }
1270  }
1271  }
1272  return offset;
1273 }
1274 
1275 // re2c macros
1276 #define RE2C_BSIZE 1024
1277 typedef struct {
1278  unsigned char *cur, *lim, *mrk, *ctx, *eof, *tok;
1279  int res;
1280  int32_t tokstart;
1281  unsigned char buffer[RE2C_BSIZE];
1282 } regex_scanner_t;
1283 
1284 #define YYCTYPE unsigned char
1285 #define YYCURSOR re2c_scur
1286 #define YYLIMIT re2c_slim
1287 #define YYMARKER re2c_smrk
1288 #define YYCONTEXT re2c_sctx
1289 #define YYFILL(n) { \
1290  RE2C_FILLBUFFER(n);\
1291  if (re2c_sres <= 0) break;\
1292 }
1293 
1294 #define REGEX_SCANNER unsigned char *re2c_scur, *re2c_stok, *re2c_smrk, *re2c_sctx, *re2c_slim;\
1295  int re2c_sres; int32_t re2c_stokstart;\
1296  unsigned char re2c_sbuffer[RE2C_BSIZE];\
1297  re2c_scur = re2c_slim = re2c_smrk = re2c_sctx = &re2c_sbuffer[0];\
1298  re2c_sres = 0;\
1299  RE2C_FILLBUFFER(0);
1300 
1301 #define REGEX_POS (-(re2c_slim - re2c_scur) + seek(0, SEEK_CUR))
1302 #define REGEX_LOOP_BEGIN do { re2c_stok = re2c_scur; re2c_stokstart = REGEX_POS;} while (0);
1303 #define REGEX_RESULT (re2c_sres)
1304 
1305 #define RE2C_DEBUG_PRINT \
1306 do {\
1307  char buf[81];\
1308  uint32_t here = seek(0, SEEK_CUR);\
1309  uint32_t d = re2c_slim - re2c_scur;\
1310  uint32_t end = here - d;\
1311  unsigned len = end - re2c_stokstart;\
1312  if (len > 80) {\
1313  unsigned skipped = len - 74;\
1314  seek(re2c_stokstart, SEEK_SET);\
1315  if (read(buf, 37) == 37)\
1316  break;\
1317  memcpy(buf+37, "[...]", 5);\
1318  seek(end-37, SEEK_SET);\
1319  if (read(buf, 37) != 37)\
1320  break;\
1321  buf[80] = '\0';\
1322  } else {\
1323  seek(re2c_stokstart, SEEK_SET);\
1324  if (read(buf, len) != len)\
1325  break;\
1326  buf[len] = '\0';\
1327  }\
1328  buf[80] = '\0';\
1329  debug_print_str(buf, 0);\
1330  seek(here, SEEK_SET);\
1331 } while (0)
1332 
1333 #define DEBUG_PRINT_REGEX_MATCH RE2C_DEBUG_PRINT
1334 
1335 #define BUFFER_FILL(buf, cursor, need, limit) do {\
1336  (limit) = fill_buffer((buf), sizeof((buf)), (limit), (cursor), (need));\
1337 } while (0);
1338 
1339 #define BUFFER_ENSURE(buf, cursor, need, limit) do {\
1340  if ((cursor) + (need) >= (limit)) {\
1341  BUFFER_FILL(buf, cursor, need, limit)\
1342  (cursor) = 0;\
1343  }\
1344 } while (0);
1345 
1346 /* Move stok to offset 0, and fill rest of buffer, at least with 'len' bytes.
1347  * Adjust the other pointers, which must be after the stok pointer!
1348  */
1349 #define RE2C_FILLBUFFER(need) do {\
1350  uint32_t cursor = re2c_stok - &re2c_sbuffer[0];\
1351  int32_t limit = re2c_slim - &re2c_sbuffer[0];\
1352  limit = fill_buffer(re2c_sbuffer, sizeof(re2c_sbuffer), limit, (cursor), (need));\
1353  if (!limit) {\
1354  re2c_sres = 0;\
1355  } else if (limit <= (need)) {\
1356  re2c_sres = -1;\
1357  } else {\
1358  uint32_t curoff = re2c_scur - re2c_stok;\
1359  uint32_t mrkoff = re2c_smrk - re2c_stok;\
1360  uint32_t ctxoff = re2c_sctx - re2c_stok;\
1361  re2c_slim = &re2c_sbuffer[0] + limit;\
1362  re2c_stok = &re2c_sbuffer[0];\
1363  re2c_scur = &re2c_sbuffer[0] + curoff;\
1364  re2c_smrk = &re2c_sbuffer[0] + mrkoff;\
1365  re2c_sctx = &re2c_sbuffer[0] + ctxoff;\
1366  re2c_sres = limit;\
1367  }\
1368 } while (0);
1369 
1377 static inline int32_t ilog2_compat(uint32_t a, uint32_t b)
1378 {
1379  uint32_t c = a > b ? a : b;
1380  if (c < 2048) {
1381  // scale up a,b to [0, 4096]
1382  uint32_t scale = 2048/c;
1383  a *= scale;
1384  b *= scale;
1385  } else {
1386  // scale down a,b to [0, 4096]
1387  uint32_t scale = (c+2047) / 2048;
1388  a /= scale;
1389  b /= scale;
1390  }
1391  // log(a/b) = log(a*scale/(b*scale)) = log(a*scale) - log(b*scale)
1392  return ilog_table[a] - ilog_table[b];
1393 }
static force_inline uint32_t getPECheckSum(void)
Definition: bytecode_local.h:771
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:259
uint16_t MajorOperatingSystemVersion
Definition: bytecode_pe.h:73
static force_inline uint32_t matches(__Signature sig)
Definition: bytecode_local.h:264
Definition: bytecode_api.h:75
Definition: bytecode_local.h:1224
static force_inline uint32_t getPESizeOfHeaders(void)
Definition: bytecode_local.h:759
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:783
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:275
enum DIS_SIZE address_size
Definition: bytecode_local.h:1227
static force_inline uint32_t getPEBaseOfCode(void)
Definition: bytecode_local.h:604
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:723
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:484
static uint16_t force_inline le16_to_host(uint16_t v)
Definition: bytecode_local.h:447
static force_inline uint16_t getPESizeOfOptionalHeader()
Definition: bytecode_local.h:912
Definition: bytecode_local.h:1210
static force_inline bool getPEisDLL()
Definition: bytecode_local.h:936
static force_inline uint32_t getPEFileAlignment(void)
Definition: bytecode_local.h:652
static uint32_t force_inline cli_readint32(const void *buff)
Definition: bytecode_local.h:472
enum X86REGS scale_reg
Definition: bytecode_local.h:1200
enum X86REGS add_reg
Definition: bytecode_local.h:1201
static force_inline bool readRVA(uint32_t rva, void *buf, size_t bufsize)
Definition: bytecode_local.h:1112
static uint32_t getVirtualEntryPoint(void)
Definition: bytecode_local.h:1065
Definition: bytecode_pe.h:36
static force_inline bool hasPEInfo(void)
Definition: bytecode_local.h:517
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:747
struct DIS_arg arg[3]
Definition: bytecode_local.h:1229
uint32_t disasm_x86(struct DISASM_RESULT *result, uint32_t len)
static force_inline uint8_t getPEMajorLinkerVersion(void)
Definition: bytecode_local.h:544
uint16_t MajorOperatingSystemVersion
Definition: bytecode_pe.h:110
static force_inline uint32_t getPESizeOfInitializedData(void)
Definition: bytecode_local.h:580
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:592
Definition: bytecode_pe.h:135
const uint16_t __clambc_kind
Definition: bytecode_api.h:233
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:831
static force_inline uint32_t getEntryPoint(void)
Definition: bytecode_local.h:1030
static uint32_t getSectionVirtualSize(unsigned i)
Definition: bytecode_local.h:1093
static force_inline uint32_t getPESizeOfCode(void)
Definition: bytecode_local.h:568
static force_inline uint32_t getPESizeOfStackReserve(void)
Definition: bytecode_local.h:807
uint32_t SizeOfInitializedData
Definition: bytecode_pe.h:65
static force_inline uint32_t getPESectionAlignment(void)
Definition: bytecode_local.h:640
static uint32_t force_inline be32_to_host(uint32_t v)
Definition: bytecode_local.h:405
uint32_t CheckSum
Definition: bytecode_pe.h:82
enum DIS_SIZE operation_size
Definition: bytecode_local.h:1226
static force_inline uint16_t getPEMinorImageVersion(void)
Definition: bytecode_local.h:699
static force_inline uint16_t getPEMajorOperatingSystemVersion(void)
Definition: bytecode_local.h:664
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:298
int32_t displacement
Definition: bytecode_local.h:1203
static force_inline uint32_t getPEWin32VersionValue(void)
Definition: bytecode_local.h:735
uint8_t MajorLinkerVersion
Definition: bytecode_pe.h:100
static uint32_t getPELFANew(void)
Definition: bytecode_local.h:989
static force_inline uint32_t getPENumberOfSymbols()
Definition: bytecode_local.h:901
static force_inline uint16_t getPEMajorSubsystemVersion(void)
Definition: bytecode_local.h:711
Definition: bytecode_pe.h:51
static force_inline uint32_t getPEDataDirSize(unsigned n)
Definition: bytecode_local.h:964
uint32_t engine_functionality_level(void)
Definition: bytecode_api.h:85
static force_inline uint32_t DisassembleAt(struct DIS_fixed *result, uint32_t offset, uint32_t len)
Definition: bytecode_local.h:1241
static force_inline overloadable_func void foundVirus(const char *virusname)
Definition: bytecode_local.h:331
enum DIS_SIZE access_size
Definition: bytecode_local.h:1199
static force_inline uint64_t getPEImageBase(void)
Definition: bytecode_local.h:628
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:855
uint64_t other
Definition: bytecode_local.h:1216
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:1003
static force_inline uint32_t getPEDataDirRVA(unsigned n)
Definition: bytecode_local.h:947
int32_t read(uint8_t *data, int32_t size)
static uint32_t getSectionRVA(unsigned i)
Definition: bytecode_local.h:1079
struct DIS_mem_arg mem
Definition: bytecode_local.h:1214
static force_inline uint16_t getPEMinorOperatingSystemVersion(void)
Definition: bytecode_local.h:676
Definition: bytecode_disasm.h:329
Definition: bytecode_local.h:1198
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:1211
static force_inline uint32_t getPESizeOfHeapCommit(void)
Definition: bytecode_local.h:843
static void force_inline cli_writeint32(void *offset, uint32_t v)
Definition: bytecode_local.h:496
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:255
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:879
uint16_t MinorOperatingSystemVersion
Definition: bytecode_pe.h:74
static force_inline uint16_t getPEMajorImageVersion(void)
Definition: bytecode_local.h:688
static force_inline uint32_t getImageBase(void)
Definition: bytecode_local.h:1054
static force_inline uint32_t getPEPointerToSymbolTable()
Definition: bytecode_local.h:890
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:349
uint8_t scale
Definition: bytecode_local.h:1202
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:819
static uint64_t force_inline be64_to_host(uint64_t v)
Definition: bytecode_local.h:434
enum X86REGS reg
Definition: bytecode_local.h:1215
static force_inline uint16_t getPEDllCharacteristics(void)
Definition: bytecode_local.h:795
static uint64_t force_inline le64_to_host(uint64_t v)
Definition: bytecode_local.h:421
static uint16_t force_inline be16_to_host(uint16_t v)
Definition: bytecode_local.h:460
static force_inline bool hasExeInfo(void)
Definition: bytecode_local.h:507
static force_inline uint32_t getPEBaseOfData(void)
Definition: bytecode_local.h:616
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:1041
static force_inline bool isPE64(void)
Definition: bytecode_local.h:533
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:556
static force_inline void * memchr(const void *s, int c, size_t n)
Definition: bytecode_local.h:1139
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:1228
enum DIS_SIZE access_size
Definition: bytecode_local.h:1212
static force_inline uint16_t getPECharacteristics()
Definition: bytecode_local.h:923
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:978
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:389
enum X86OPS x86_opcode
Definition: bytecode_local.h:1225
static force_inline uint16_t getPEMachine()
Definition: bytecode_local.h:868
static int32_t ilog2_compat(uint32_t a, uint32_t b)
Definition: bytecode_local.h:1377