https://wiki.multimedia.cx/index.php?title=RE_process&feed=atom&action=historyRE process - Revision history2024-03-28T18:51:31ZRevision history for this page on the wikiMediaWiki 1.39.5https://wiki.multimedia.cx/index.php?title=RE_process&diff=11749&oldid=prevKostya: /* Hijack code flow */2009-07-10T15:21:13Z<p><span dir="auto"><span class="autocomment">Hijack code flow</span></span></p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 08:21, 10 July 2009</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l40">Line 40:</td>
<td colspan="2" class="diff-lineno">Line 40:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>When you redirect the functions make sure you declare your replacement function with the right call convention.</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>When you redirect the functions make sure you declare your replacement function with the right call convention.</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td colspan="2" class="diff-side-deleted"></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2" class="diff-side-deleted"></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;">Alternatively, you can install debug trap and use it to gather data at any given point of execution. It may be slow but certainly replaces debugging with GDB.</ins></div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>== Strategy ==</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>== Strategy ==</div></td></tr>
</table>Kostyahttps://wiki.multimedia.cx/index.php?title=RE_process&diff=11748&oldid=prevKostya: /* Information gathering */2009-07-10T15:08:16Z<p><span dir="auto"><span class="autocomment">Information gathering</span></span></p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 08:08, 10 July 2009</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l7">Line 7:</td>
<td colspan="2" class="diff-lineno">Line 7:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>* The second thing is to collect different decoder for the codec. Sometimes debug symbols are available in one binary but not the other.</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>* The second thing is to collect different decoder for the codec. Sometimes debug symbols are available in one binary but not the other.</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>* Read the product/codec whitepapers, they are mostly useless but can give a hint of the techniques used in the codec.</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>* Read the product/codec whitepapers, they are mostly useless but can give a hint of the techniques used in the codec.</div></td></tr>
<tr><td class="diff-marker" data-marker="−"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div> </div></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;">* Sometimes looking into frame data can give you enough information without even having a decoder. For example, constant frame sizes usually mean DPCM or similar compression; deflated data starts with 'x'; [[MS RLE]] data can be detected by special codes at the end; some individuals can even recognise H.26x bitstream.</ins></div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>== Get it running ==</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>== Get it running ==</div></td></tr>
</table>Kostyahttps://wiki.multimedia.cx/index.php?title=RE_process&diff=11747&oldid=prevMerbanan: Initial how to RE codecs article2009-07-10T09:36:18Z<p>Initial how to RE codecs article</p>
<p><b>New page</b></p><div>The not so simple introduction to RE'ing of multimedia codecs.<br />
<br />
== Information gathering ==<br />
Try to collect as much public knowledge as possible.<br />
<br />
* The first thing to do is to collect/create sample files. Without samples files there is nothing to test/verify a reimplementation.<br />
* The second thing is to collect different decoder for the codec. Sometimes debug symbols are available in one binary but not the other.<br />
* Read the product/codec whitepapers, they are mostly useless but can give a hint of the techniques used in the codec.<br />
<br />
<br />
== Get it running ==<br />
If you get a binary running it is much more easy to figure out how it works exactly. Getting it running in a controlled environment is even better.<br />
<br />
* Mplayer has a dll loader which makes it very easy to load acm and dmo codecs.<br />
* Use the technique described here to load a binary under Linux: http://multimedia.cx/pre/re-xan.html<br />
* Run it on the original platform in some form.<br />
<br />
<br />
== Picking it apart ==<br />
Load up the codec in a dissassembler.<br />
<br />
* Get Idapro and let it chew through the binary.<br />
* Somehow locate the code paths in the codec that is used. http://multimedia.cx/eggs/category/reverse-engineering/callret-monitor/ describes one way.<br />
<br />
== Hijack code flow ==<br />
If the codec is running in a deterministic way it is possible to runtime patch the code to replace call addresses. The following macros can be used:<br />
<br />
#define insert_native_addr(address, replacement) \<br />
{ \<br />
unsigned int *padd = (unsigned int *)address; \<br />
*padd = (unsigned int*)replacement; \<br />
};<br />
<br />
#define insert_native_call(address, replacement) \<br />
{ \<br />
*((uint8_t*)address) = 0xe8; \<br />
*((int32_t*)(address+1)) = (int) replacement - address - 5; \<br />
};<br />
<br />
When you redirect the functions make sure you declare your replacement function with the right call convention.<br />
<br />
<br />
== Strategy ==<br />
Most codecs work in a init, decode, close fashion. The init step allocated a codec private context that is then passed to the decode function.<br />
The private context is used by the codec to store it's internal state needed for decoding. The close function just cleans up the context. First<br />
start with reverse engineering the init and use a malloc wrapper to figure out the structure of the private context. Then go for the main decode function.<br />
It usually takes the private context as arguments and the indata buffer and size. From here the progress is open ended, try to tackle functions at the<br />
end of the decode call tree and at the start. That way knowledge about parameters can propagate through the code.<br />
<br />
== Reimplementation ==<br />
When all the code is understood replace the code with lavc equivalents and re implement the stuff that is missing.</div>Merbanan