<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri","sans-serif";
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri","sans-serif";
mso-fareast-language:EN-US;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:42.5pt 42.5pt 42.5pt 70.85pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=UK link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span lang=EN-US>= Preamble =<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>The task I'm working on is somewhat unorthodox, but I'd like to get some comments anyway.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>I'm writing "semi-stealth" DLL which is one loaded by the process (and visible by others) while not residing on disk as a file. This is done by the following method:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>1. Call LoadLibrary on an existing DLL file<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>2. Take memory snapshot of the loaded DLL<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>3. Call FreeLibrary on it and delete DLL file.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>4. Create KnownDlls kernel section object, obtain its new base address.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>5. Process relocations and imagebase fixups, write such patched image to kernel section.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Now whenever a process tries to load DLL normally by magic name, it is loaded from this kernel section, not from file.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>= Problem =<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>As long as I use minimalistic DLL with single "invoke MessageBoxW" (written in masm) everything works just fine.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Then comes the following:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>---<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>library demo;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>uses Windows;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>begin<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> MessageBoxW(GetDesktopWindow,'Demo window','Demo',MB_OK or MB_ICONINFORMATION);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>end.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>---<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>This one is failing by causing AV upon loading from kernel section. I narrowed down this problem as being caused by the implicitly linked code from _FPC_DLL_Entry as well as initialization section of system.pp. The first failure is caused by this:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>---<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> { pass dummy value }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> StackLength := CheckInitialStkLen($1000000);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> StackBottom := StackTop - StackLength;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>---<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>These are threadvars, but the helper functions SysAllocateThreadVars() and suchlike are only initialized _later_ in the code with the call of InitSystemThreads(). Therefore, AV ensues since SysAllocateThreadVars() is being called by the now invalid absolute addresses. I wonder why it even works normally.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>At first I thought InitSystemThreads() was the only culprit since it remembers the addresses of threadvar and other helper functions. But placing it prior to access to StackLength did not help much. There seems to be alot of other stuff that remembers other function's addresses in such a way that they are not recalculated upon DLL reload. I tried to figure out in what order the procedure calls between begin and end in system.pp should be rearranged but that didn't help either. Finally, as a last resort, I commented out everything that was in system.pp's begin-end section and now my "library" is “working” just fine. I understand though that this method implies stripping most of FPC juicy features like strings, memory management, maybe arrays etc and that I can't really do much without it.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>= Question =<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>First, I'd like to know why calling of DLL entry point anew does not re-initialize _all_ RTL internals regardless of what was remembered prior to taking the snapshot. Is it just assuming good behavior of system loader that carefully zeroes data segment while I don't?<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Second, I'd be glad to hear any suggestions of workarounds, such as:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>a) is there a way to supply specially modified system.ppu/o compile-time depending on what source file is being compiled?<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>or<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>b) is there a way to somehow IFDEF the initialization section in system.pp so that my DLL code can not have it while everything else can?<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>or<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>c) should I take care to zero data segment after the relocations are processed?<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>or (in the ideal Universe)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>d) is there a proper order of calling the initialization routines in the system.pp section that makes sure EVERY helper function gets its address variable updated prior to using?<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Thank you all in advance.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Best Regards,<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Gennadiy.<o:p></o:p></span></p></div></body></html>