![]() |
Studna > ╚lßnky > Runtime Error at ... > RTE 00:06 |
![]()
Runtime Error at 00:06 aneb SpustitelnΘ soubory
V tomto dφle RTEΦka je menÜφ pojednßnφ o spustiteln²ch souborech. Snahou bylo zp°φstupnit co nejvφce informacφ o souborech typu EXE, COM, DLL a tak dßle. ╚erpal jsem z n∞kolika dokument∙ a trochu se r∙znφ, tak₧e snad vyberu jen to nejlepÜφ.
COM program
NejstarÜφ spustiteln² soubor, kter² se objevoval snad u₧ pod operaΦnφm systΘmem CP/M a jeÜt∞ nynφ se objevujφ guruovΘ, kte°φ je pφÜφ (nap° fox :-)))).
Program typu com se cel² nahrßvß do jednoho segmentu, tudφ₧ jeho dΘlka musφ b²t nejvφce FFFFh bytes (ale v∞tÜinou asi o 200 bytes menÜφ) a musφ mφt data a k≤d v tomto jednom segmentu. Nemß hlaviΦku a na zaΦßtku je (v∞tÜinou) skok na startovacφ mφsto. Obvykle se program nahrßvß od adresy 100h (myslφm, ₧e se to nastavuje p°φkazem org 100h, ale ruku bych za to do ohn∞ nedal), Φeho₧ se dß vyu₧φt pro n∞jakΘ samozobrazovßnφ (viz. RTE at 00:02) nebo podobnΘ akce. StaΦφ si ·pln∞ na konec programu v assembleru dßt label jako ukazatel na data a potΘ klasick²m p°φkazem copy /b program.com + data.dtx program.com vytvo°it com program i s daty (musφte ovÜem dßt pozor na dΘlku koneΦnΘho souboru !!!!!!!).
EXE program
Nov∞jÜφ nßstupce comu, v∞tÜina z nßs se s nφm ji₧ setkala :-), proto₧e ho vytvß°ejφ skoro vÜechny kompilßtory od tasm p°es bp a delphi a₧ po kompilßtory cΘΦka. S p°φchodem windows∙ se jejich struktura mφrn∞ zm∞nila a rozÜφ°ila.
EXE program zaΦφnß hlaviΦkou, kterß je NEJM╔N╠ 32 bytes dlouhß, ale m∙₧e byt i delÜφ (nap°. tasm vytvß°φ hlaviΦku dlouhou 512 bytes). HlaviΦka je tzv. paragraph-aligned, co₧ znamenß, ₧e jejφ dΘlka je v nßsobcφch 16ti (pokud je hlaviΦka 512-aligned, dos ji pr² zavßdφ rychleji).
Klasickß hlaviΦka DOSovskΘho programu mß tuto strukturu:
nßzev offset dΘlka popis Signat 00h word .exe signatura, v∞tÜinou word 5A4Dh = 'MZ' nebo 4D5Ah = 'ZM' PartPag 02h word poΦet byt∙ v poslednφ strßnce (strßnka=512 bytes) PageCnt 04h word poΦet strßnek i s hlaviΦkou (poslednφ strßnka, kterß nemß 512 bytes) se zapoΦφtßvß takΘ) ReloCnt 06h word poΦet polo₧ek v relokaΦnφ tabulce HdrSize 08h word dΘlka hlaviΦky v paragrafech (zapoΦφtßvß se i relokaΦnφ tabulka), hodφ se pro nalezenφ poΦßtku zavßd∞nΘho modulu v souboru) MinMem 0Ah word minimßlnφ pam∞¥ pot°ebnß za koncem programu (v paragrafech) MaxMem 0Ch word maximßlnφ pam∞¥ pot°ebnß za koncem programu (v paragrafech), je-li MinMem = MaxMem = 0, program je nahrßn co nejv²Üe ReloSS 0Eh word poΦßteΦnφ hodnota SS relativnφ ke startu programu (musφ se relokovat) ExeSP 10h word poΦßteΦnφ hodnota registru SP ChkSum 12h word kontrolnφ souΦet (dopln∞k k souΦtu vÜech word∙ souboru) ExeIP 14h word poΦßteΦnφ hodnota registru IP ReloCS 16h word poΦßteΦnφ hodnota pro nastavenφ CS (musφ se relokovat) TablOff 18h word pozice prvnφ relokaΦnφ tabulky v souboru (v∞tÜinou na pozici 001Ch) Overlay 1Ah word Φφslo overlaye (pro hlavnφ program 00h)DΘlka hlaviΦky (formßtovanΘho zßhlavφ) je 1Ch. Z tΘto tabulky se dajφ vypoΦφtat zajφmavΘ hodnoty, pou₧itelnΘ pro prßci s exe-programy. Nap°φklad dΘlka zavßd∞nΘho modulu exe-souboru se vypoΦφtß takto:
((PageCnt*512)-(HdrSize*16)-PartPag;Celkovß dΘlka exe-souboru se vypoΦφtß takto:
If PartPag=0 then PartPag:=512; ((PageCnt-1)*512)+PartPag;DΘlka hlaviΦky (nebo offset zavßd∞nΘho modulu - zaΦφnß zde t∞lo exe-souboru):
HdrSize*16;Za formßtovanou Φßstφ hlaviΦky dßle nßsleduje relokaΦnφ tabulka (pokud je ReloCnt <> 0) o dΘlce ReloCnt * 4 s tφmto formßtem:
![]()
RelokaΦnφ tabulka se pou₧φvß z d∙vodu, ₧e exe program m∙₧e b²t nahrßn na jakoukoliv adresu (do libovolnΘho segmentu) a vÜechny ukazatele na pam∞¥ (nap°. FAR CALL, dlouhΘ pam∞¥ovΘ ukazatele a odkazy typu MOV AX,data_seg) musφ b²t upraveny na adresy, na kterΘ jsou nahrßny. To se provßdφ nßsledovn∞:
var i, t_ofs, t_seg, relo_seg, hodnota:word for i:=1 to relocnt do begin {opakuj pro kazdou polozku} nacti t_ofs, t_seg {nacti ze souboru polozku jako dva wordy} relo_seg := start_seg + t_seg {pricti startovaci segment} hodnota := memw[relo_seg:t_ofs] {nacti aktualni hodnotu} hodnota := hodnota + start_seg {pricti k ni start. segment} memw[relo_seg:t_seg] := hodnota {uloz hodnotu zpet} endTak a mßme upraveny vÜechny skoky a odkazy na segment, v kterΘm je program nahrßn. Dßle se jeÜt∞ musφ upravit hodnoty pro ReloSS a ReloCS tφm, ₧e k nim op∞t p°iΦteme startovacφ segment.
Za relokaΦnφ tabulkou nßsleduje v²pl≥ na hranici paragrafu a pak ji₧ samotnΘ t∞lo programu.
Detailnφ popis nahrßvßnφ exe souboru je v²born∞ popsßn v SYSMANovi, tak₧e to sem nebudu p°episovat.
novΘ p°φdavky
Asi tak nejd∙le₧it∞jÜφm zßsahem do programu exe jsou ·pravy pro novΘ OS (jako nap°φklad wind≤zy a OS/2).
Zda se jednß o tento formßt programu se dß zjistit naΦtenφm doublewordu na adrese 3Ch od zaΦßtku souboru, pokud je na tΘto adrese n∞co ne₧ 00000000h (co₧ je pro klasick² dosovsk² program - jak kdy, pokud mß program dlouhou relokaΦnφ tabulku, tak ta zasahuje i do tΘto Φßsti a tento doubleword obsahuje n∞co jinΘho ne₧ 0), podφvßme se na tuto adresu. Zde by m∞lo b²t n∞jakΘ slova z tΘto tabulky:
NE windows nebo os/2 1.x "new executable" program (segmentovan²) LE windows virtual device driver (VxD) (lineßrnφ) LX varianta LE pou₧φvanß v os/2 2.x W3 windows WIN386.EXE soubor (kolekce LE soubor∙) W4 windows95 VMM32.VXD soubor PE win32 (win NT a win32s) p°enositeln² program zalo₧en² na Unix COFFPokud tam je, jednß se o n∞jak² rozÜφ°en² formßt exe souboru (pokud ne, jednß se o dosovsk² exe program). Tyto programy majφ takΘ obvyklou dosovou hlaviΦku, ve kterΘ jsou hodnoty odkazujφcφ na tzv. stub program (kra¥oulinkat² exe), kter² nßm vypφÜe, ₧e "This program must be run under Microsoft Windows." nebo "This program cannot be run in a DOS session." a odskoΦφ zp∞t do dosu. Tato hlaviΦka je v∞tÜinou 82h bytes dlouhß (obvykle obsahuje i n∞kterou z v²Üe uveden²ch signatur rozÜφ°enΘho exe souboru) a neobsahuje relokaΦnφ tabulku (obvykle).
Stub-program si m∙₧eme naprogramovat sami (ale jde to jen v C-Φku, paskalu asi ne) a ud∞lat nap°φklad program, kter² ve woknech napφÜe, ₧e vy₧aduje dos a ukonΦφ se (tak, jak to d∞lajφ windousovskΘ programy v dosu). Ve stub-programu se m∙₧e provßd∞t skoro cokoliv, akorßt musφ b²t kratÜφ ne₧ 64kb a relokaΦnφ tabulka stub-u musφ b²t za adresou 003Dh (co₧ pr² nenφ problΘm pro Φerstv∞ zkompilovanΘ nebo PKLITEm zabalenΘ programy).
V²bornou ukßzkou vyu₧itφ stub-u jsou pomocnΘ programy ke QEMMu 8.0 od Quarterdecku, kterΘ majφ stub ud∞lan², aby se v dosu spustila dosovskß verze a ve windousech se spustil windousowskß verze (d∞lß to nap°. Manifest). Za nevhodnΘ pova₧uji to, kdy₧ si windousowsk² program spuÜt∞n² v dosu spustφ windousy se sebou (kdo mß Φekat na to, a₧ se mu to spustφ, ne ?!?!)
Jedna poznßmka: DLL knihovny (.dll) , screensavery (.scr), fonty (.fon), knihovny OCX, VBX, device drivery (.drv) jsou vÜechno spustitelnΘ programy (majφ rozÜφ°enφ 'PE', 'NE' nebo 'LE'). Jo, TrueType fonty majφ formßt shodn² s fonty v os/2 (schvßln∞ se podφvejte na truetype font z w95 a najd∞te si °et∞zec 'OS/2'.
V hlaviΦce exe-souboru se takΘ dajφ nalΘzt informace o tom, Φφm byl program linkovßn, pakovßt atd. Zde je popis toho zajφmav∞jÜφho:
Borland TLINK
offset 1Eh byte signatura FBh 1Fh byte verze TLINK u (hlavnφ Φφslo ve vyÜÜφch 4 bitech, vedlejÜφ v ni₧Üφch)ARJ - samorozbalovacφ archφv
offset 1Ch dword signatura "RJSFX" (starÜφ verze, novß signatura je "aRJsFX" v prvnφch 1000 bytech souboruLZEXE 0.90 zabalen² spustiteln² soubor
offset 1Ch dword signatura "LZ09"LZEXE 0.91 zabalen² spustiteln² soubor
offset 1Ch dword signatura "LZ91"PKLITE zabalen² spustiteln² soubor offset 1Ch byte vedlejÜφ Φφslo verze 1Dh byte bity 0-3: hlavnφ Φφslo verze bit 4: extra komprese bit 5: velk² (multi-segmentov²) soubor 1Eh 6 bytes signatura "PKLITE" nßsledovanß zprßvou o copyrightu
LHarc 1.x samorozbalovacφ archφv
offset 20h 3bytes skok na start vybalovacφho k≤du 25h 12 bytes signatura "LHarc's SFX"LHA 2.x samorozbalovacφ archφv
offset 24h 10 bytes signatura "LHa's SFX" (verze 2.10) nebo "LHA's SFX" (v 2.13)RAR samorozbalovacφ archφv
offset 1Ch 4 bytes signatura "RSFX"Jak pou₧φvat data, p°ipojenß k EXE souboru
P°ipojenφ dat k exe souboru se provßdφ znßm²m zp∙sobem (jen pro p°ipomenutφ: copy /b program.exe + data.dtx program2.exe. Jak ale na tato data p°istupovat. Dß se to provΘst takto:
var f:file; pagecnt,partpag:word; dummy:word; seeking:longint; begin assign(f,paramstr(0)); reset(f,1); {otevre sam sebe} blockread(f,dummy,2);{preskoci 'MZ'} blockread(f,partpag,2);{nacte pocet bytu na posledni strance} blockread(f,pagecnt,2);{nacte pocet stranek} if partpag=0 then partpag:=512;{pokud je posledni stranka 512-bytes aligned} seeking:=(pagecnt-1)*512+partpag;{kde zacinaji data} seek(f,seeking);{presuneme se na konec} end;Zde jen malß poznßmka:
- Pokud je partpag rovno nule, je program zarovnßn na 512 bytes, a jeliko₧ pagecnt je poΦet strßnek i s ne·plnou strßnkou, musφme polo₧ku partpag (pokud je nulovß) naplnit hodnotou 512.
- Funkce FileSize v borland pascalu vracφ celkovou dΘlku programu, tedy i s p°ipojen²mi daty, proto m∙₧eme vypoΦφtat dΘlku p°ipojen²ch dat pomocφ filesize(f)-seeking, co₧ se obΦas m∙₧e hodit.
Jinak p°iklßdßm takΘ zdrojßky k mΘ unit∞ Mygrp, kterß se starß o prßci s group-soubory (vφce soubor∙ spojen²ch do jednoho velkΘho), zjiÜ¥uje si sama, zda je grp soubor p°ipojen za exe-program nebo je mimo, pou₧φvß kompresi (voliteln∞) a tak dßle.
Jak p°evΘst com na exe
To se provede velice jednoduÜe. P°ipravφme si 32 bytes dlouhou hlaviΦku a za nφ zapφÜeme cel² com soubor. Je nutnΘ si uv∞domit, ₧e dos nahrßvß t∞lo exe souboru na adresu PSP+10h:0 a p°ipoΦφtßvß ji k ReloCS a tato hodnota je pak CS programu. ProblΘm je v tom, ₧e com program se nahrßvß na adresu PSP segmentu, proto musφ mφt polo₧ka ReloCS hodnotu FFF0h, kterß je pak p°idßna k hodnot∞ PSP+10h a zφskßvßme PSP segment.
Progrßmek by mohl vypadat takto:
program com2exe; {nevytvari true-exe!} type hlava=record signature:array[1..2]of char; {'MZ' nebo 'ZM'} partpag:word; {pocet bytes v posledni strance} pagecnt:word; {pocet stranek} relocnt:word; {pocet relokacnich polozek} hdrsize:word; {delka hlavicky v paragrafech (*16 bytes)} minmem:word; {minimalni potrebna pamet} maxmem:word; {maximalni potrebna pamet} reloss:word; exesp:word; chksum:word; {kontrolni soucet (vetsinou 0)} exeip:word; relocs:word; tabloff:word; {zacatek relokacni tabulky (ofs od zacatku)} overlay:word; {pocet overlayu (vetsinou 0)} end; var fi,fo:file; h:hlava; dummy:longint; i,j:integer; b:array[1..2048]of byte; begin writeln('com2exe convertor v0.1 freeware by paulsoft/no!future (c) 1997'); writeln; if paramcount<>2 then writeln('parameterz: infile.com outfile.exe') else begin {$i-}assign(fi,paramstr(1)); reset(fi,1); if ioresult<>0 then begin writeln('error while opening input file'); halt(1); end; assign(fo,paramstr(2)); rewrite(fo,1); {$i+} if ioresult<>0 then begin writeln('error while opening output file'); halt(1); end; h.signature:='ZM';{at se trochu lisime} h.partpag:=(filesize(fi)+32) mod 512; {pocet bytu v posledni strance} h.pagecnt:=round((filesize(fi)+32)/512)+1; {pocet stranek} h.relocnt:=0; {relokacni tabulku nepotrebujem} h.hdrsize:=2; {delka hlavicky je 2 paragrafy (32bytes)} h.minmem:=($ffff-filesize(fi))div 16; {minimum pameti} h.maxmem:=$ffff; {maximum pameti - vsechna} h.reloss:=$fff0; {pretece to} h.exesp:=$fffe; {vlastnost comu} h.chksum:=0; h.exeip:=$100; {vlastnost comu} h.relocs:=$fff0; {stejne jako sp} h.tabloff:=0; {relokacni tabulku nepotrebujem - cokoliv} h.overlay:=0; {overlaye nemame} blockwrite(fo,h,sizeof(h)); dummy:=$114A5010;{musime doplnit hlavicku na 32bytes} blockwrite(fo,dummy,sizeof(dummy)); repeat blockread(fi,b,sizeof(b),i); blockwrite(fo,b,i,j); until (i=0)or(i<>j); close(fi); close(fo); writeln('converting done'); end; end.jak si do hlaviΦky text napsat
Do hlaviΦky si m∙₧eme napsat jakΘkoliv texty nebo si ji m∙₧eme zkompresovat (nap°. po kompilaci tasmem se vytvß°φ hlaviΦka dlouhß 512 bajt∙, ale mohla by b²t dlouhß t°eba jen 48 bajt∙). StaΦφ si p°eΦφst hlaviΦku, relokaΦnφ tabulku, v hlaviΦce upravit pozici relokaΦnφ tabulky, dΘlku hlaviΦky v paragrafech, doplnit hlaviΦku na dΘlku paragrafu (tzn. aby jejφ dΘlka byla d∞litelnß 16ti bezezbytku) a vÜe zapsat do novΘho souboru i s t∞lem programu. M∙₧eme si do hlaviΦky zapsat takΘ n∞jakΘ texty a ud∞lat v podstat∞ to sam² a kdekdo bude p°ekvapen, co to v tΘ hlaviΦce mßme.
Napsal jsem takΘ progrßmek v pascalu, jmenuje se exetext.pas, kter² toto vÜechno provßdφ (mßm pocit, ₧e i hlaviΦku zkrßtφ). Program funguje, ale obΦas funguje trochu zßhadn∞, proto₧e mi dos po spuÜt∞nφ upravenΘho souboru oznamuje, ₧e tento exe mß Üpatn² formßt :-(( Tak₧e neruΦφm za poÜkozenφ program∙!!!!!!! (Jß vßs varoval).
Doufßm, ₧e jsem pokryl skoro vÜechno pot°ebnΘ.
Zdar Pavel
Pou₧itß literatura:
Advanced linking 1, 2 - Φlßnek v Φasopise Imphobia 10 od Ervina z Abaddon
Sysman 3.1
Ralf Brown's Interrupt List Release 53 (12.1.97)Pou₧itΘ programy:
Hacker's View v 4.16 by SEN 1991-1993
Hexlist v0.2 by paulsoft/no!future 1997
kontakt: jislp@feld.cvut.cz http http://cs.felk.cvut.cz/~jislp/ irc kanßly #cs, #cz, #cesi; nick xpj
[ Zp∞t nahoru ]
Copyright © 1997, 1998 Pavel Jisl, jislp@feld.cvut.cz