Archive for 30. sept. 2010

Sai natuke Internet Exploreri reklaamide blokeerijat täiustatud

september 30, 2010

Üldiselt projekt adBlackout on mul pooleli, samas kenasti töötab URLi põhine blokeerimine.

Täpsemalt programmist:

https://tingmarprog.wordpress.com/2009/08/08/adblackout-reklaamide-blokeerija-ie-jaoks/

Miks ma seda nö enda jaoks kiirelt täiustasin – seekord on süüdlaseks Messengeri reklaamid, täiesti hulluks ajavad. Kasutan tööalaselt seda ja siis tuleb mingi venekeelne jura, siis hüppab mul mingi flashreklaam sealt välja karjub, laulab …pidin sõnavarast lausa sõna wtf välja võtma.

Võtsin ette enda adBlackout mooduli ja panin Messengeri reklaami “killah” funktsionaalsuse sisse, peale seda on võimalik häirimatult Messengeri kasutada. Loomulikult oleks saanud mingeid reklaamiserveri url’e keelata, see pole nii efektiivne meetod, mida mina kasutan.

Selle mooduli installeerimisel sulgege IE, siis kopeerige kuhugi endale sobivasse kataloogi ning konsooli aknas (cmd) kirjutage regsvr32 adBlackout.dll

Download

Kui moodul beta statusest välja saab, siis teen ka normaalse installeerimise paketi. Hetkel on install natuke “hack-in-dos” stiilis 😉

Kui moodul installitud, siis käivitage Internet Explorer ja vajutage F9 ning valige programmis msni reklaami keelav märkeruut.

Advertisements

Hmm..EPL muutunud ehituspoeks ?

september 16, 2010

Kas “mõjus” kommentaaride kinnikeeramine või miskit muud, aga alamdomeenis nüüd ehituspood ?!

http://bauhof.epl.ee/

Programmeerimine: küsime Delphi app kaudu Google Pagerank’i

september 16, 2010

See Google Pagerank kood ammu levinud PHP’s , aga eile panin tähele stackoverflows, et üks inimene küsis seda ja seal oli PHP kood Delphi klassiks transleeritud. Lihtsalt sportlik huvi tekkis, et kas asi ka töötab.
Kuna seal kasutati D2009, siis mul kasutamiseks vaid D7 tuli mõningad pisimuudatused teha ja vuala asi töötab nagu loom. Ühenduse loomisel kasutasin Indy 10.2.5 libraryt, kes viitsib võib asju läbi winineti teha.

Failis lähtekood ja ka kompileeritud binary, mis ranki kuvab.

http://ingmar.planet.ee/avalikud_programmid/googlepagerank.zip

Hirmus oli tõdeda, et mu kodulehe pagerank jääb kõvasti blogile alla :)))

Programmeerimine: DLL laadimine ja IAT tabeli kontroll

september 13, 2010

Natukene siis kadunud tehnilist hiina keelt :)))

Räägin standardsest Windowsi PE32 failist (*.exe). Antud faili päises on tihti päris palju sektsioone, export section, data, import section jne

Meid huvitabki import section. Seal paikneb info (staatiliselt laetud) dll’ide kohta, mida me kasutame, koos funktsioonide nimedega. Nüüd kui programm käivitatakse, siis hakkab laadija import sektsiooni läbi kammima (staatiliselt lingitud dll) ja kenasti laeb protsessi piirkonda dll’i ning funktsiooni nimede massiiv asendatakse nende funktsioonide aadressitega. Süsteemsed dll’id kernel32, ntdll.dll jne laetakse vaid op.süsteemis vaid korra, aga laadija teab, kuidas käituda.

Kes nö vahet ei tee, siis ntx delphis on staatiline dll laadimine. Ehk programmi käivitamisel toimub laadimine:

function InetIsOffline(dwFlags: DWORD): BOOL; stdcall;
– function InetIsOffline; external ‘url.dll’ name ‘InetIsOffline’;

Dünaamiline, dll laetakse siis, kui vaja antud objekti funktsioone kasutada
type
TInetIsOffline = function (dwFlags: DWORD): BOOL; stdcall;

var
pInetOff :TInetIsOffline ;

pinst:=loadlibrary(‘url.dll’);
pInetOff:=getprocaddress( pinst,’InetIsOffline’);

freelibrary(pinst);

Mis vahe kahel laadimisel, esimese eelis see, et laadija teeb ära töö loadlibrary ja hiljem ka freelibrary. Tegelt ta teeb selle igal juhul ära, isegi kui kusagil unustad ära freelibrary ning programm lõpetab töö.
Staatiline linkimine natuke kiirem, samas (!) ntx kui mingi DLL puudu, siis programm ei käivitud ja võib saada ebameeldivat tehnilist sõimu.

Hea küll, on ka nö delay load, mida kasutatakse. Aga see süsteem, et on programmis loader, kui pöördutakse funktsiooni poole, siis alles dllid laetakse mällu. Kui ma ei eksi, siis .NETil on enamus dll’e delay loaded.

Aga nagu mõnel koosolekul tuleb öelda, asume nüüd ikka ka asja kallale / räägime, kus point:

Kujutage ette, laete ntx crypt32.dll mällu ja see tihti laetakse programmides STAATILISELT ! Nüüd mul on vaja kindlaid protseduure hakata jälgima, tahan ikka teie suuri saladusi teada saada.
Kõige lihtsam meetod, teen proxy dll’i. Ehk sisuliselt programmiga samas kataloogis on crypt32.dll, kuna laadija võtab esmalt kataloogis olevad dllid, siis see laetaksegi. Ja see proxy dll omakord laeb õige crypt32.dll’i

Minu soovitus:
turvalisusega tegelev tarkvara (ka meie ID kaardi tarkvara) peaks laadima .dll’e dünaamiliselt ja täispikka otsinguteed kasutades. Tarkvara teeb kindlaks windowsi süsteemi kataloogi ja siis teeb ala loadlibrary(‘c:\windows\system32\crypt32.dll’). See lihtne samm välistaks nö proxy dll häki.

Aus olla, spetsialistid ei viitsi neid proxy dll’e teha, kõiki neid API’sid forwardida, neid võib sadu olla. Mina ka ei viitsiks, samuti ei pruugi olla lihtne programmi kataloogi kirjutada (Vista/W7) Siis tuleb märksõna DLL injection – sisuliselt laen oma DLL’i sinu programmi külge, sisuliselt selle tegevusega saan ligipääsu programmi mälule.

Milleks see ligipääs hea ? Lihtne näide, ma saan nüüd muuta funktsioonide aadresse, mis dll staatilisel laadimisel omistati. Kui ma oleksin rott viljasalves…siis suunaksin vajalikud crypt32.dll API’d läbi injectitud DLLi. Samuti “varastaksin” ära API’d, mis eluliselt suht tähtsad programmile: loadlibrary, getprocessaddress, getmodulehandle . Nüüd kui laeksite programmis suvalist DLLi, siis saaksin mina otsustada, et mida ikka “reaalselt” laeme.

Kunagi mõtlesin, et mis oleks lahendus, kuidas programmi turvalisemaks muuta ! Siis tulin ideele, kasutada suht kaootiliselt dokumenteeritud FS registrit.

Ehk teisisõnu me võrdleme, kas loadlibrary funktsiooni aadress ikka klapib sellega, mida laadija meile tagastas. Juhul, kui ei klapi, siis teame, meid on “häkitud” / hackintosh kallal.

Preudokood:
>
> p:=getprocaddress(getmodulehandle(‘kernel32.dll’),’LoadLibraryA’)
>

peab võrduma läbi FS registri saadud LoadLibraryA aadressiga. Lihtne kas pole :))

FS registri kaudu saame teada kernel32 aadressi ja sealt aadressilt loeme export tablest välja LoadLibrary aadressi. Ehk teisisõnu, kui antud funktsioon annab true väärtuse, siis on programmi häkitud ja targem oleks kohe sulgeda ennast.

Näiteks kunagi tegin programmi multiregion/, tema kasutabki kuupäevade muutmiseks IAT häkki. Samas minu testprogramm koos järgneva turvafunktsiooniga kenasti tuvastas, et teda muudetud.

Kood töötas küll kenasti XP peal, kahjuks W7 veel ei tea.


function detectIATHook(var debbugerAlsoPresent : Boolean):Boolean;
// Author: Ingmar Tammeväli
// http://ingmar.planet.ee/programmeerimine
Type
PIMAGE_DOS_HEADER = ^_IMAGE_DOS_HEADER;
PIMAGE_NT_HEADERS = ^_IMAGE_NT_HEADERS;
PIMAGE_EXPORT_DIRECTORY = ^_IMAGE_EXPORT_DIRECTORY;

Type
PDWordArray = ^TDWordArray;
TDWordArray = Array [0..$FFFFF] of DWORD;

const
CAddrLower = $7000000;

Type
PWordRec = ^DWordRec;
DWordRec = packed record
case Integer of
0: (Lo, Hi: word);
1: (Bytes: array [0..1] of word);
end;

PJmpRec = ^TJmpRec;
TJmpRec = record
OpCode: Word; //$FF25(Jmp, FF /4)
Addr : DWordRec;
end;

type
TIsDebbugerPresent = function : boolean;stdcall;

var
basePointer : Pointer;
dos : PIMAGE_DOS_HEADER;
nt : PIMAGE_NT_HEADERS;
exportdir : PIMAGE_EXPORT_DIRECTORY;
i : Integer;
fFunctName : PAnsichar;
fLoadLibraryA : Pointer;
fGetModuleHandle : Pointer;
fGetProcAddr : Pointer;
fIsDebbugerPresent : Pointer;
// ---
IsDebbugerPresent: TIsDebbugerPresent;
fChkCallPtr : PPointer;
tmp : DWord;
begin
try

result:=false;
{
Sarnase koodi võib ka viirustest leida; kasutame vaenlast enda kasuks ära
Otsime kernel32.dll originaalaadressi Kuna IAT hookide tuvastamiseks peame saama kasutada "originaal kerneli" API'sid.
}
basePointer:=nil;
fLoadLibraryA:=nil;
fGetModuleHandle:=nil;
fGetProcAddr:=nil;
fIsDebbugerPresent:=nil;
debbugerAlsoPresent:=False;

asm
mov eax, dword ptr fs:[30h] // PEB
mov eax, dword ptr [eax+0ch] // PEB_LDR_DATA
mov esi, dword ptr [eax+1ch] // nimistu algus
lodsd
mov ebx, dword ptr [eax+08h]
xchg ebx,basePointer
end;

// ------------
// alla selle aadressi kernelit lihtsalt ei laeta
if dword(basePointer)<CAddrLower then
exit;

// normaalses olukorras peaks need aadressi klappima; vähemalt W2K/WinXP all asjad klapivad
// vista võib aadressitega mängida
result:=(getmodulehandle('ntdll.dll')dword(basePointer)) and // võib olla vanemate SP puhul
(getmodulehandle('kernel32.dll')dword(basePointer));
if result then
exit;

basePointer:=pointer(getmodulehandle('kernel32.dll'));
// okei...nüüd meid huvitavad API'd GetModuleHandle, GetProcAddress
// proovime otsida nüüd originaal aadressid; käime export table läbi
dos:=PIMAGE_DOS_HEADER(basePointer);
//goto the kernel base address
if (dosnil) and (dos^.e_magic=IMAGE_DOS_SIGNATURE) then
begin
nt:=pointer(cardinal(dos)+dos^._lfanew);
if (nt^.Signature=IMAGE_NT_SIGNATURE) then
if nt^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress>0 then
begin
exportdir:=PIMAGE_EXPORT_DIRECTORY(cardinal(dos) +
nt^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
for i:=0 to exportdir^.NumberOfNames-1 do
begin
fFunctName:=(pointer(cardinal(dos)+
PDWordArray(Pointer(dword(exportdir^.AddressOfNames)+dword(dos)))[i]));
// LoadLibraryW selle variandi võite täiendavalt lisada
if fFunctName='LoadLibraryA' then
fLoadLibraryA:=(pointer(cardinal(dos)+
PDWordArray(Pointer(dword(exportdir^.AddressOfFunctions)+dword(dos)))[i]))
else
if fFunctName='GetModuleHandleA' then
fGetModuleHandle:=(pointer(cardinal(dos)+
PDWordArray(Pointer(dword(exportdir^.AddressOfFunctions)+dword(dos)))[i]))
else
if fFunctName='GetProcAddress' then
fGetProcAddr:=(pointer(cardinal(dos)+
PDWordArray(Pointer(dword(exportdir^.AddressOfFunctions)+dword(dos)))[i]))
else
if fFunctName='IsDebuggerPresent' then // vajadusel ka CheckRemoteDebuggerPresent
fIsDebbugerPresent:=(pointer(cardinal(dos)+
PDWordArray(Pointer(dword(exportdir^.AddressOfFunctions)+dword(dos)))[i]));
end;
end;
end;

// meil peavad olema 3 API aadressid, vastasel juhul mingi viga algoritmis
if assigned(fLoadLibraryA) and
assigned(fGetModuleHandle) and
assigned(fGetProcAddr) then
begin
// loadlib check
with PJmpRec(@loadlibrary)^ do
begin
tmp:=0;
DWordRec(tmp).Lo:=Addr.Lo;
DWordRec(tmp).Hi:=Addr.Hi;
fChkCallPtr:=ppointer(ptr(tmp))^;
result:=(fChkCallPtrfLoadLibraryA);
if result then
exit;
end;

// getprocaddress check
with PJmpRec(@getprocaddress)^ do
begin
tmp:=0;
DWordRec(tmp).Lo:=Addr.Lo;
DWordRec(tmp).Hi:=Addr.Hi;
fChkCallPtr:=ppointer(ptr(tmp))^;
result:=(fChkCallPtrfGetProcAddr);
if result then
exit;
end;

// getmodulehandle check
with PJmpRec(@getmodulehandle)^ do
begin
tmp:=0;
DWordRec(tmp).Lo:=Addr.Lo;
DWordRec(tmp).Hi:=Addr.Hi;
fChkCallPtr:=ppointer(ptr(tmp))^;
result:=(fChkCallPtrfGetModuleHandle);
if result then
exit;
end;

IsDebbugerPresent:=getprocAddress(getmodulehandle('kernel32.dll'),'IsDebuggerPresent');
if assigned(IsDebbugerPresent) then
begin
result:=(@IsDebbugerPresentfIsDebbugerPresent);
if result then
exit;
// -----------
debbugerAlsoPresent:=IsDebbugerPresent
end;
// ---
result:=false;
end;
except
end;
end;