Windows - A Windows Rundll32 interfésze

A Rundll32 interfész segítségével többféle parancsot indíthatunk el, mint ahogy a kapcsolódó cikkek között erre példát is láthatunk. Ez a kezdetben belső használatra készített eszköz alkalmas arra, hogy a kifejezetten számára írt függvényeket meghívja egy DLL állományból. Cikkünkben bemutatjuk a használatát.
A Windows 95/98/Me operációs rendszerek két parancssori interfészt tartalmaznak, amelyek segítségével meghívható egy DLL állomány valamely függvénye. Ez a két parancs a Rundll.exe és a Rundll32.exe. A Rundll a 16-bites, míg a Rundll32 pedig a 32-bites DLL-ek esetében használható. Cikkünkben a továbbiakban csak a Rundll32-vel foglalkozunk, mivel a Windows NT vonal (NT 4, 2000, XP, 2003) nem támogatja a 16-bites parancsot, vagyis a Rundll alkalmazást.
A Rundll32 nem teszi lehetővé, hogy bármilyen függvényt bármely DLL-ből hívjunk, pl.: valamely Win32 API-t valamely rendszer DLL-ből. Ezt a programot csak olyan függvénytárakhoz használhatjuk, amelyeket kifejezetten úgy készítettek el, hogy így meghívhatók legyenek.
A Rundll32 eszköz is, mint sok hasonló alkalmazás, csak belső használatra készült a Microsoft-nál, de mivel eléggé általános a működési mechanizmusa, ezért elérhető általános használatra.
Rundll32 parancssor
A Rundll32 parancssora a következőképpen néz ki:
rundll32.exe <dllnév>,<belépési_pont> <opcionális argumentumok>
Az alábbi egy példa:
rundll32.exe setupapi,InstallHinfSection DefaultInstall 132 c:\windows\inf\ie.inf
Három dologra kell ügyelnünk a parancssor használatakor:
  • A Rundll32 az adott DLL fájlnevet a szokásos helyeken keresi (az alkalmazás indítási könyvtára, aktuális könyvtár, rendszerkönyvtár, windows könyvtár, path könyvtárak). Javasolt teljes utat megadni a DLL-hez, hogy biztosítsuk azt, hogy a megfelelőt találja meg az alkalmazás. A legjobb eredmény elérése érdekében használjuk a rövid fájlnevet a hosszú név helyett, ami biztosítja, hogy ne jelenjenek meg tiltott karakterek.
  • A <dllnév> nem tartalmazhat szóköz-karaktert vagy vesszőt, idéző jeleket. Ez a Rundll parancssori elemzőjének korlátja.
  • A fenti parancssorban a vessző (,) a <dllnév> és a <belépési_pont> között rendkívül fontos. Ha a vessző hiányzik, akkor a Rundll32 hibával leáll anélkül, hogy hibaüzenetet jelenítene meg. Emellett nem lehet szóköz-karakter a <dllnév>, a vessző, és a <belépési_pont> függvény között.
Hogyan működik a Rundll32?
A Rundll32 az alábbi lépéseket hajtja végre:
  • Értelmezi a parancssort.
  • Betölti a meghatározott DLL-t a LoadLibrary() segítségével.
  • Megszerzi a <belépési_pont> függvény címét a GetProcAddress() segítségével.
  • Meghívja a <belépési_pont> függvényt, átadja a parancssor végét, amely az <opcionális argumentumok> felsorolása.
  • Amikor a <belépési_pont> függvény visszatért, a Rundll32.exe törli a DLL-t a memóriából és kilép.
Hogyan írjunk saját DLL-t?
A DLL-ünkben írjuk meg a <belépési_pont> függvényt a következő prototípussal:
void CALLBACK
EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
Ismét három dologra kell odafigyelni, a belépési pont függvénnyel kapcsolatban:
  • Nyilvánvalóan a "belépési_pont" nevet le kell cserélni az aktuális belépési pont függvény nevére. Ügyeljünk arra, hogy a Rundll32 belépési pontja teljesen mást jelent, mint a DllEntryPoint függvény egy 32-bites DLL-ben, amely a folyamatok és szálak befűzési és leválasztási értesítését kezeli.
  • A Rundll32 számára készül belépési függvénynek _stdcalll hívó szokás szerint kell definiáltnak lennie (CALLBACK alapértelmezetten használja az _stdcall attribútumot). Ha az _stdcall attribútum hiányzik, akkor a függvény a _cdecl hívási konvencióra áll, és ezután a Rundll32 hibásan áll le, miután meghívta a függvényt.
  • Mióta _stdcall hívási konvenció szerint kell definiálni a függvényt, ezt követi a Visual C++ fordító aktuális exportja, mint _EntryPoint@16, ha a DLL C-ben íródott, vagy használnunk kell újabb név dekorációt, ha a DLL C++-ban íródott. Ügyeljünk arra, hogy a megfelelően exportált nevet használjuk parancssorban a Rundll32-höz. Ha a dekorált nevek használatától meg akarjuk óvni magunkat, akkor használjunk .def fájlt, és exportáljuk a belépési funkciót név szerint.
A paraméterek a Rundll32 belépési ponthoz a következők:
Paraméter Leírás
hwnd Ablakkezelő, amely gazdaablakként lesz használva minden DLL által létrehozott ablakhoz.
hinst DLL példánykezelő.
lpszCmdLine ASCIIZ parancssor a DLL-hez, amelyet elemez.
nCmdShow Leírja, hogy hogyan jelenjen meg a DLL ablaka.
Az alábbi példában:
rundll32.exe setupapi,InstallHinfSection DefaultInstall 132 c:\windows\inf\ie.inf
A Rundll32-nek meg kell hívnia az InstallHinfSection() belépési pont függvényt a Setupapi.dll-ben, és átadnia a következő paramétereket:
Paraméter Leírás
hwnd (szülő ablakkezelő)
hinst HINSTANCE a setupapi.dll-hez
lpszCmdLine "DefaultInstall 132 c:\windows\inf\ie.inf"
nCmdShow (bármi, amit az nCmdShow átadott a CreateProcess-nek)
Ügyeljünk arra, hogy a <belépési_pont> függvény az, amelynek értelmeznie kell a saját parancssorát (lpszCmdLine) és használnia a szükséges paramétereket. A Rundll32.exe csak az opcionális argumentumokig elemzi a parancssort. Az értelmezés véget ér a <belépési_pont> függvénnyel.
A cikkben használt példa újratelepíti az Internet Explorert.