home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / disasm / source / runtime_tracedec.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  5.7 KB  |  209 lines

  1. #include "runtime_tracedec.h"
  2.  
  3. namespace {
  4.     bool VDDisasmMatchRule(VDTracedecContext *pContext, const unsigned char *source, const unsigned char *pattern, int pattern_len, int bytes, const unsigned char *&source_end);
  5.  
  6.     bool VDDisasmApplyRuleset(VDTracedecContext *pContext, const unsigned char *rs, const unsigned char *source, int bytes, const uint8 *&source_end) {
  7.         while(rs[0] || rs[1]) {
  8.             const unsigned char *src_end;
  9.             const unsigned char *result = rs + rs[0] + 1;
  10.             const unsigned char *match_next = result + 1;
  11.  
  12.             if (VDDisasmMatchRule(pContext, source, rs+1, rs[0]>>1, bytes, src_end)) {
  13.                 uint8 flags = *result;
  14.  
  15.                 if (flags & 0x80) {
  16.                     switch(flags) {
  17.                         case 0x80:    pContext->bSizeOverride = true; break;
  18.                         case 0x81:    pContext->bAddressOverride = true; break;
  19.                         case 0x82:    pContext->bRepnePrefix = true; break;
  20.                         case 0x83:    pContext->bRepePrefix = true; break;
  21.                     }
  22.                 } else {
  23.                     pContext->mFlags |= flags;
  24.                     pContext->bFinal = true;
  25.                 }
  26.  
  27.                 source_end = src_end;
  28.                 return true;
  29.             }
  30.  
  31.             rs = match_next;
  32.         }
  33.  
  34.         return false;
  35.     }
  36.  
  37.     bool VDDisasmMatchRule(VDTracedecContext *pContext, const unsigned char *source, const unsigned char *pattern, int pattern_len, int bytes, const unsigned char *&source_end) {
  38.         while(bytes && pattern_len) {
  39.             if (!pattern[1] && pattern[0]) {
  40.                 if (pattern[0] & 0x80) {
  41.                     int count = pattern[0] & 0x3f;
  42.  
  43.                     if (pattern[0] & 0x40)
  44.                         --source;
  45.                 
  46.                     const uint8 *src_end;
  47.  
  48.                     if (!VDDisasmApplyRuleset(pContext, pContext->pRuleSystem[count+1], source, bytes, src_end))
  49.                         return false;
  50.  
  51.                     source = src_end;
  52.                 } else if (pattern[0] < 16) {
  53.                     if (pattern[0] > bytes)
  54.                         return false;
  55.  
  56.                     source += pattern[0];
  57.                     bytes -= pattern[0]-1;
  58.                 } else {
  59.                     switch(pattern[0]) {
  60.                     case 16:    if (!pContext->bSizeOverride)        return false;    break;
  61.                     case 17:    if (!pContext->bAddressOverride)    return false;    break;
  62.                     case 18:    if (!pContext->bRepnePrefix)        return false;    break;
  63.                     case 19:    if (!pContext->bRepePrefix)            return false;    break;
  64.                     case 20:    if (pContext->pszSegmentOverride)    return false;    break;
  65.                     case 21:    if (!(pContext->rex & 8))            return false;    break;
  66.                     }
  67.                 }
  68.             } else {
  69.                 uint8 b = *source++;
  70.  
  71.                 if ((b & pattern[1]) != pattern[0])
  72.                     return false;
  73.             }
  74.             pattern += 2;
  75.             --bytes;
  76.             --pattern_len;
  77.         }
  78.  
  79.         if (!pattern_len) {
  80.             source_end = source;
  81.             return true;
  82.         }
  83.  
  84.         return false;
  85.     }
  86. }
  87.  
  88. bool VDTraceObjectCode(VDTracedecContext *pvdc, const uint8 *source, int bytes, VDTracedecResult& res) {
  89.     const uint8 *src2 = source;
  90.     const uint8 *src_end;
  91.  
  92.     pvdc->bAddressOverride = false;
  93.     pvdc->bSizeOverride = false;
  94.     pvdc->bRepePrefix = false;
  95.     pvdc->bRepnePrefix = false;
  96.     pvdc->bFinal = false;
  97.     pvdc->mFlags = 0;
  98.     pvdc->pszSegmentOverride = NULL;
  99.     pvdc->rex = 0;
  100.  
  101.     do {
  102.         if (VDDisasmApplyRuleset(pvdc, pvdc->pRuleSystem[0], src2, bytes, src_end) && pvdc->bFinal) {
  103.             res.mbIsCall    = 0 != (pvdc->mFlags & 0x01);
  104.             res.mbIsJcc        = 0 != (pvdc->mFlags & 0x02);
  105.             res.mbIsJmp        = 0 != (pvdc->mFlags & 0x04);
  106.             res.mbIsReturn    = 0 != (pvdc->mFlags & 0x08);
  107.             res.mbIsInvalid    = 0 != (pvdc->mFlags & 0x10);
  108.             res.mbTargetValid = false;
  109.             res.mRelTargetSize = -1;
  110.  
  111.             if (res.mbIsCall || res.mbIsJcc || res.mbIsJmp) {
  112.                 switch(pvdc->mFlags & 0x60) {
  113.                     case 0x00:
  114.                         break;
  115.                     case 0x20:
  116.                         res.mBranchTarget = (pvdc->physToVirtOffset + (ptrdiff_t)src_end) + ((sint8 *)src_end)[-1];
  117.                         res.mbTargetValid = true;
  118.                         res.mRelTargetSize = 1;
  119.                         break;
  120.                     case 0x40:
  121.                         res.mBranchTarget = (pvdc->physToVirtOffset + (ptrdiff_t)src_end) + ((sint16 *)src_end)[-1];
  122.                         res.mbTargetValid = true;
  123.                         res.mRelTargetSize = 2;
  124.                         break;
  125.                     case 0x60:
  126.                         res.mBranchTarget = (pvdc->physToVirtOffset + (ptrdiff_t)src_end) + ((sint32 *)src_end)[-1];
  127.                         res.mbTargetValid = true;
  128.                         res.mRelTargetSize = 4;
  129.                         break;
  130.                 }
  131.             }
  132.  
  133.             res.mInsnLength = src_end - source;
  134.             return true;
  135.         }
  136.  
  137.         bytes -= (src_end - src2);
  138.         src2 = src_end;
  139.     } while(bytes);
  140.  
  141.     return false;
  142. }
  143.  
  144. void *VDTracedecDecompress(void *_dst, const unsigned char *src, int src_len) {
  145.     const unsigned char *src_limit = src + src_len;
  146.     unsigned char *dst = (unsigned char *)_dst;
  147.  
  148.     // read ruleset count
  149.     int rulesets = *src++;
  150.     unsigned char **prstab = (unsigned char **)dst;
  151.  
  152.     dst += sizeof(unsigned char *) * (rulesets + 1);
  153.  
  154.     // decompress rulesets sequentially
  155.     for(int rs=0; rs<rulesets; ++rs) {
  156.         prstab[rs+1] = dst;
  157.  
  158.         const unsigned char *pattern_cache[4][2];
  159.  
  160.         while(src[0] || src[1]) {
  161.             unsigned char packctl;
  162.             int packsrc, cnt;
  163.  
  164.             // read pack control uint8 and copy prematch-literal-postmatch for pattern
  165.             packctl = *src++;
  166.             packsrc = packctl >> 6;
  167.  
  168.             int prematch = (packctl & 7) * 2;
  169.             int postmatch = ((packctl>>3) & 7) * 2;
  170.             int literal = (*src++ - 1) * 2;
  171.  
  172.             *dst++ = literal + prematch + postmatch;
  173.  
  174.             const unsigned char *pattern_start = dst;
  175.  
  176.             for(cnt=0; cnt<prematch; ++cnt)
  177.                 *dst++ = pattern_cache[packsrc][0][cnt];
  178.  
  179.             for(cnt=0; cnt<literal; ++cnt)
  180.                 *dst++ = *src++;
  181.  
  182.             for(cnt=0; cnt<postmatch; ++cnt)
  183.                 *dst++ = pattern_cache[packsrc][1][cnt-postmatch];
  184.  
  185.             // cycle pattern cache
  186.  
  187.             for(cnt=3; cnt>0; --cnt) {
  188.                 pattern_cache[cnt][0] = pattern_cache[cnt-1][0];
  189.                 pattern_cache[cnt][1] = pattern_cache[cnt-1][1];
  190.             }
  191.  
  192.             pattern_cache[0][0] = pattern_start;
  193.             pattern_cache[0][1] = dst;
  194.  
  195.             // read pack control uint8 and copy prematch-literal-postmatch for result
  196.             *dst++ = *src++;
  197.         }
  198.  
  199.         src += 2;
  200.  
  201.         *dst++ = 0;
  202.         *dst++ = 0;
  203.     }
  204.  
  205.     prstab[0] = prstab[rulesets];
  206.  
  207.     return dst;
  208. }
  209.