http://www.CodeBreakers-Journal.com
AddingfunctionstoanyprogramusingaDLL
Dracon
Abstract
SometimeagoIhaveworkedonDouby’s”ReverseMe1”andaddedmissingfunctionstotheprogram.AfterdoingthisIlookedforawaytomakethisprocesseasier.It’sveryuncomfortabletocodewithHIEW,especiallyifyoumustchangethefinishedcode.SuddenlyIgotanidea:whynotwritingadll?Thisallowsyoutousethelanguageyouaremostfamiliarwith(ASM,C,C++,Delphi,...),onlyfewasm-codeisneededandit’snotdifficult.Keywords:ReverseCodeEngineering;AddingFunctionality;DLL
TheCodeBreakers-Journal,Vol.1,No.1(2004)
I.Introduction
Target:douby’sReverseMe1EssayLevel:IntermediateToolsused:
••••
HIEWIDASICE
acompilerthatcancreateDLLs(VC++,MASM,Delphi,...)
Thisismysecondessayabout”addingfunctions”,Ihopeyouenjoyitasmuchasthefirstone.PleasevisitmyHomepage.
II.HowtowriteaDLL
WritingaDLLissimple.Firstofallyouwillneeda”DEF”filewhichspecifiesthefunctionsorvariablestoexport.Thisisasimpletextfile,hereisanexample:LIBRARYtstdll
DESCRIPTION\"Onlyatest-dll.\"EXPORTSTestProc1
”LIBRARY”isthenameofyourdll,”DESCRIPTION”thedescription(optional)andafter”EXPORTS”youcanaddallthefunctionsyouwanttoexport.
Functionscanbeexportedbyname(thisisthedefault)orbyordinal,anumbergreaterthan0.Usingthisapproachwillmakecallingeasierbecauseyoudon’tneedthewholenamebutonlyanumber.Anotherproblemwithnamesisthatthecompilerwillmodifythem:TestProc1withoneDWORDasparameterwouldbecome”_TestProc1”withC-linkageand”?TestProc1@@YAXPAUHWND__@@@Z”ifyourC++compilermanglesthename.Thisisnotonlylongbutalsohardtoremember,sobetteravoidit.YoucanalsospecifytheNONAMEparameterandnofunctionnamewillappearinyourdll.That’swhatIprefersoyourEXPORTS-lineshouldlooklikethis:
EXPORTS
TestProc1@1NONAMETestProc2@2NONAME
\"@1\"meansthatthefunctionshouldbeexportedasordinal1.
NowyoumusttelltheLinkerthatitshouldcreateadll.It’seasyifyouuseVC++:choose”New...”andthen”Win32Dynamic-LinkLibrary”intheProject-Tab.Createablankfile,addthelinesabovetocreateadefinitionfileandsaveitas”my_dll.def”(”my_dll”isthenameofyourdllofcourse).ForMASMyoumustusethefollowingcommands(puttheminabatch-file):
\\masm32\\bin\\ml/c/cofftstdll.asm
\\masm32\\bin\\Link/SUBSYSTEM:WINDOWS/DLL/DEF:tstdll.deftstdll.objImportantarethe”/DLL”switchandthenameofyourDEF-file.
DLLsdon’thavea”WinMain”functionbut”DllMain”.Readagoodbook(Petzold)orlookatmycodeformore,it’snotdifficult.Themainpurposeistoallocate/freeadditionalmemoryand/ordosomeinitialization.
2
c2004andpublishedbytheCodeBreakers-Journal.Singleprintorelectroniccopiesforpersonaluseonlyarepermitted.ReproductionandCopyright
distributionwithoutpermissionisprohibited.
TheCodeBreakers-Journal,Vol.1,No.1(2004)
III.CallingDll-functions
NowthatyouknowhowtocreateaDllwewanttocallitfromourtargetprogram.Firstyoumustloadthelibraryintomemory(LoadLibraryA).Thedllmustbeinthesamedirectoryastheotherprogramorsomewhereinthepath,elseWindowswon’tfindit.Thenextstepistogettheaddressofthefunctionyouwishtocall(GetProcAddress)andfinallyyoucancallit.It’spossibletousedifferentcalling-conventions.__pascal,__fortran,and__syscallarenolongersupportedinVC++6,sothevalidonesarenow:
1)1.STDCALL:usedinalmostallWin32Api-function.Theparametersarepushedfromrighttoleft(reverseorder!)andthecalledfunctionisresponsibleforadjustingthestack.C++functionsinVC++additionallystorethe”this”pointerinECX(THISCALL).
Shortintermezzo:Thestackisthememorythatisusedforlocalvariablesandforfunction-parameters,thepointerisstoredinESP.Every”push”and”pop”willmodifyitandit’snecessarytokeepitconsistent.Thestackgrowsfromthehighestmemoryaddresstothelowest,soifyou”add”somethingtoitthepointerwillactuallysetbackandmorestack-memoryisavailable.
2)C:theparametersarepushedfromrighttoleftandthecallerisresponsibleforadjustingthestack.ThisisthedefaultforC-functionsinVC++.Theadvantageisthatyoucanusevariableargumentse.g.sprintf,butitalsoresultsinslightlybiggercode.
3)FASTCALL:FirsttheregistersECXandEDXareused,thenthestack(Watcomhasusedmoreregisters...).Thecalledfunctionmustadjustthestack.Whichoneshouldwechoose?Isuggesttoyouuse”STDCALL”(__stdcallinVC++)becauseyoudon’thavetomessaroundwiththestack.Defineyourfunctionlikethis:
void__stdcallTestProc1(DWORDdwTest,doubledTest);
Ifyouusethedefault(__cdecl)youmustadjustthestack.That’snotdifficult:sumupthesizeofeveryparameteranddoa”addesp,(sum)”afterthecall.Intheexampleaboveit’sDWORD(4)+double(8)=0Chsoyoumustwrite”addesp,0Ch”.Afterallthistechnicalinformationlet’sreturntoourcode.Thelaststepistounloadthedll.WhenaprogramexitsallDLLs(ifnotneededbyotherprograms)willberemovedsoit’snotnecessarytofreeitinthemiddleofyourprogram,especiallyifyouwanttouse”static”variables.Ontheotherhand,don’tleavemarkseverywhereyouhavebeen.:-)Use”FreeLibrary”tounmapyourDLLfrommemory.pushoffset\"mydll.dll\"callLoadLibraryAmovesi,eaxpush1pusheax
callGetProcAddresspushparameter1calleax
;addesp,4pushesi
callFreeLibrary...
;nameofyourdll
;storehandleinesi
;ordinal1:firstfunction
;functionexpects1parameter;adjustthestackifnecessary
;dosomeotherstuffandreturncontrol
Thisisthebasiccode.Somehowweneedtheaddressesofthe3Api-functions.Usetheprogram”OpGen”byNeuRaLNoiSEtogetthem,itcansavealistwithallimportedfunctions.Sometimes”LoadLibraryA”or”FreeLibrary”aren’timported.Inthatcaseyoumustdothefollowing:
3
c2004andpublishedbytheCodeBreakers-Journal.Singleprintorelectroniccopiesforpersonaluseonlyarepermitted.ReproductionandCopyright
distributionwithoutpermissionisprohibited.
TheCodeBreakers-Journal,Vol.1,No.1(2004)
pushoffset\"kernel32.dll\"callGetModuleHandleApushpushcallmov
offset\"LoadLibraryA\"eax
GetProcAddressebx,eax
;thefunctionisin\"kernel32.dll\"
;Kernel32.dllisalreadyloaded,weonlyneed;thecurrenthandle
;thisisthehandleforkernel32.dll;storeitsomewhere
”GetModuleHandleA”and”GetProcAddress”arealwaysimported,Ihaven’tseenaprogramwithoutthemyet.Nowyoucanuse”callebx”tocall”LoadLibraryA”.
LoadLibraryAwillloadaDLLintomemoryandincreaseitsreferencecounter.Anothercallwouldn’tloadthedllasecondtime(andwastememory)butonlyincreasetheref-counter.GetModuleHandleAwillNOTloadtheDLLbutretrievethehandleofanalreadyloadedDLL,theref-counterwon’tbeincreased.FinallyacalltoFreeLibrarywilldecreasetheref-counter,ifithasreached0theDLLwillbeunloaded.Onprogram(process)exitWindowsremovesalllibrariesfrommemoryunlesstheyarestillusedbyotherprograms.
IV.AnExample:AddingCRC32-calculationtoDouby’sReverseMe1
Theoryisnecessarybutapractialexampleisbetter.IwillusetheReverseMetoaddanewfunctiontotheprogram:calculatetheCRC32ofthecurrenttext.Thiswillgiveyouanideahowsmallchangeswillresultinaverydifferentnumber.Theonlyparameterweneedisthehandleofthemainwindow.
Thisessaydoesn’tshowyouhowtofindtheplacetoaddcode,pleasereadmyotherbigessayhowtodoit.Youwillfindajmp-tablewhichtakescareofthecommand-IDs.It’sinterestingthatonevalueisnotused,thissimplifiesmanythings.Start”BRW”orSymantec’s”ResEdit”toaddanewmenu-itemandgiveittheID40002.Good,mynewcodewillstartatphysicaloffset0x3B40(virtualoffset0x403B40).Whatdoweneed?AddressesoftheApi-Functions:LoadLibraryA(0x00404028)GetProcAddress(0x0040402C)GetModuleHandleA(0x00404044)
Hmm,”FreeLibrary”isnotimported.Ihaveshownyouabovewhattodointhatcase.Offsetsforsomestrings(useaHex-Editortoenterthem):\"patch_dll.dll\"(virtualoffset0x403F00,phys.0x3F00)\"kernel32.dll\"(0x403F10)\"FreeLibrary\"(0x403F20)
Herewego!Firstwemustpatchthejmp-table(0x1260),the2ndentry(0x1264)shouldpointtoournewcode(0x403B40)sostartyourHex-Editorandchange:37124000into403B4000.
ThefollowingcodemustbeenteredinHIEW.MyFINISHcodestartsatoffset0x3C00,butyoucanputitclosertotheothercode,thiswillmakealljumps”short”.IfyouenterjumpsinHIEW(jmp,jne,...)youmustalwaysusethephysicaloffset.AfterpressingF9(Update)youwillseetowhichlocationthejumpactuallygoes.
4
c2004andpublishedbytheCodeBreakers-Journal.Singleprintorelectroniccopiesforpersonaluseonlyarepermitted.ReproductionandCopyright
distributionwithoutpermissionisprohibited.
TheCodeBreakers-Journal,Vol.1,No.1(2004)
;newcodewhichcallsadll-function;startingatoffset0x3B40;
;LoadDllintomemorypush403F00
calld,[00404028]oreax,eaxjzFINISHmovesi,eax
;getaddressofwishedfunctionpush1pusheax
calld,[0040402C]oreax,eaxjzFINISH;pushparametersandcallitpush[esp+10h]calleax;add
esp,4
;;;;;offset\"patch_dll.dll\"LoadLibraryA
eax!=0(libraryloaded?)enterinHIEW:jz3C00storehandleinesi
;;;;ordinal1(1stexportedfunction)handletodllGetProcAddressfunctionfound?
;window-handle,checkmyotheressay;callthefunction
;adjustthestackifnecessary
;getaddressofFreeLibraryandcallit;noerror-checking,shouldalwayswork:-)push403F10;offset\"kernel32.dll\"calld,[00404044];GetModuleHandleApush403F20;offset\"FreeLibrary\"pusheax;handlekernel32.dllcalld,[0040402C];GetProcAddresspushesi;handleto\"patch_dll.dll\"calleax;FreeLibraryjmpFINISH;Cleanup-code
;CommandIDwashandled,sowecanreturnFINISH:popedipopesipopebxret10h
WhilecodingtheDLLIhavefoundabug(orfeature)withtheWM_GETTEXTmsg:mybufferhasasizeof0x10000andIusedthisvaluetogetthetextoftheedit-control.Whathappenend?Nothing!AftersometryingIfoundoutthatyoucanonlyuseWORD-values:
GetWindowText(hWnd,pBuffer,0xFFFF);GetWindowText(hWnd,pBuffer,0x10000);DownloadthesourceofthepatchDLLusedinthisessay.
//thisworks//thisdoesn’t
5
c2004andpublishedbytheCodeBreakers-Journal.Singleprintorelectroniccopiesforpersonaluseonlyarepermitted.ReproductionandCopyright
distributionwithoutpermissionisprohibited.
TheCodeBreakers-Journal,Vol.1,No.1(2004)
V.ConclusionandGreetings
UsingaDLLismuchmorecomfortablethanmodifyingthetarget-programdirectly.Youcan(1)useanylanguage,(2)don’tneedtoplayaroundwiththePE-sections,(3)createbigcodeandyourownresources(dialogs,...)and(4)reuseyourfunctions.Themostdifficultthingistofindagoodplacefromwhereyoucancallyourfunctions.InCorASMapplicationsthisisnoproblem,butMFC,Delphi,VB,etc.needalotofreversing.
Asanexcerciseyoucanaddthemissingfunctions(load,save,exit)totheReverseMe1.Practiceisnecessarytogetusedtoit,readingisnotenough.Ithinkwithmyfirstessayandthisoneyouhavetherequiredknowledge,andyoucanalwayssendmeamailifyouhaveproblems.Bigshoutsgooutto:
KnottyDread(heistheman...)NeuRaLNoiSE(hegotskillz...)
Iczelion(checkhis{Win32ASM}site)
Razzia(hewasthefirstwhohasaddedfunctionstoaprogram)sˆwitz(coolwebmasterandPerl-wizard)Douby(fellowfromDREAD)
MACERandPotsmoke(funnyguysfromEFNET)allDREADmembers
Comments,critics,improvements,questionsshouldgoto:andreas(dot)theDragon(at)gmx(dot)net
6
c2004andpublishedbytheCodeBreakers-Journal.Singleprintorelectroniccopiesforpersonaluseonlyarepermitted.ReproductionandCopyright
distributionwithoutpermissionisprohibited.
因篇幅问题不能全部显示,请点此查看更多更全内容