Archive for the ‘Koodivaramu’ Category

Windows 10 Raspberry Pi 2 jaoks …

august 12, 2015

..paistab, et peab hakkama katsetama 😉

http://ms-iot.github.io/content/en-US/Downloads.htm

Advertisements

phpBB keelame ntx slaavikeelsed postitused…

märts 9, 2015

Leidsin enda Stiigo foorumist ühe unustatud triggeri / päästiku. Kuna spämmerid innovatiivsed ja tihti isegi captcha ning kontrollküsimused pole piisav.

Siis tasub spämmerite elu teistmoodi ebamugavaks teha:

* phpBB soovitan teha keelatud märksõnade listi, ntx brändinimed asendada sõnaga SPAM
* kui teil puhtalt eestikeelne foorum; siis antud trigger aitab seda ka nii hoida

DELIMITER $$

CREATE TRIGGER TRG_I_less_spam BEFORE INSERT ON stiigo_posts FOR EACH ROW

begin
declare msg varchar(255);

IF (LOCATE(‘võlusõna’, new.post_text) < 1) AND ((CHAR_LENGTH(REPLACE(convert(new.post_text using latin1),'?','')) / CHAR_LENGTH(new.post_text)) * 100) <55 THEN
set msg = 'Do something useful or to post use magic keyword…';
signal sqlstate '45000' set message_text = msg;
END if;

END

$$
DELIMITER ;

OpenCV: leiame pildilt palgi…

detsember 21, 2014

Mõtlesin, et üle pika aja testin võrratu OpenCV (2.4 ja VC9) võimalusi ja natuke ka meenutan C++, mida kahjuks igapäevaselt ei kasuta. Võtsin eesmärgi teha nö lihtsa prototüübi, mis suudaks leida pildilt palgi(d). Mingi sarnane rakendus vist kunagi võitis Ajujahi.

Üldiselt algoritm lihtne ja seda saab aina rohkem täiustada. Antud kood leiab “ümmargused” asjad, olgu see lillepott, coca cola purk või loeb ümmargused ehted kuusel kokku.
Parima tulemuse saab loomulikult, kui objekti on suht otse pildistatud.

Soovitav täiustus algoritmi, et võrreldaks ringi suurust tervikpildi suurusega. Et ring poleks liiga pisike ja liiga suur. Seda saab edukalt teostada funktsiooni HoughCircles kahe viimase parameetriga.

Lõikame leitud ringi fragmendi välja ja küsime keskmise värvuse. Te saate algoritmi täiustada, kui võtate ringist kaks fragmenti. Siis saate täpsema keskmise värvuse, mina hetkel võtan vaid ühe.

pilt1

win32 binary saab alla laadida siit

Programmi väljakutse “circle.exe linkpildile”

Koodifragmendi panen seekord siia:

#include “stdafx.h”

#include <iostream>
#include “cv.h”
#include “highgui.h”

#include “cxcore.h”
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>
#include <cmath>
#include <vector>
#include <algorithm>

#include “opencv.hpp”
#include <string>

using namespace cv;
using namespace std;

int ColorAsRGB(int Red, int Green, int Blue)
{
return (Red*65536)+(Green*256)+Blue;
}

int _tmain(int argc, _TCHAR* argv[])
{
std::string fname = argc >= 2 ? argv[1] : “test.jpg”;
cv::Mat src = cv::imread(fname);

cv::Mat pdest;
cv::Mat gray;

// selle kohaga olge ettevaatlik; järsku peaks pildi veel väiksemaks teisendama
cv::resize(src, pdest, Size(1024, 768), 0, 0, INTER_CUBIC);
cv::cvtColor(pdest, gray, CV_BGR2GRAY);

GaussianBlur( gray, gray, cv::Size(9, 9), 2, 2 );

vector<Vec3f> circles;

HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 2, gray.rows/4, 200, 100);

if (circles.size() < 1)
HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 1, gray.rows/8, 200, 20, 35, 0);

// debug
std::cout << circles.size() <<std::endl;
for( size_t i = 0; i < circles.size(); i++ )
{

Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
// —
int radius = cvRound(circles[i][2]);

int x = cvRound(circles[i][0]);
int y = cvRound(circles[i][1]);
int delta = 5;

Point tlc( x-(radius+delta),y-(radius+delta));
Point brc( x+(radius+delta),y+(radius+delta));

Rect roi_rect(brc, tlc);

// lõikame regiooni välja keskmise värvuse jaoks
IplImage iplimg = pdest;
cvSetImageROI(&iplimg,roi_rect);

Mat roiimg = cvarrToMat(&iplimg);
cvResetImageROI(&iplimg);

// mis värv seal ikka siis rohkem domineerib
cv::Scalar rgbcolavg =cv::mean(roiimg);

int rgbval = ColorAsRGB(rgbcolavg[2],rgbcolavg[1], rgbcolavg[0]);

// Teoreetiline PUIDU värvus; värske männipuit ntx
// Soovitan seda väärtus tweakida, siis tuvastus täpsem;
// See on lihtsalt int muutuja koos RGB väärtustega
if ((rgbval >= 11704411) && (rgbval <= 16048566))
{

// joonistame ristküliku ümber
cv::rectangle( pdest,tlc,brc,Scalar( 0, 255, 255 ),1,8 );

// joonistame leitud “ringile” ringi ümber
circle( pdest, center, 3, Scalar(0,255,0), -1, 8, 0 );

// joonistame leitud ringile keskpunkti
circle( pdest, center, radius, Scalar(0,0,255), 3, 8, 0 );

// kuvame siis leitu
stringstream ss;
ss << “leitudRing ” << i;
string caption = ss.str();

cv::imshow(caption, pdest);

// väike debug
printf(“%.0f/%.0f/%.0f %d”, rgbcolavg[0], rgbcolavg[1], rgbcolavg[2], rgbval);
printf(” %d \n”,radius);

}
}

cv::waitKey(0);
return 0;
}

OpenCV: leiame pildilt autonumbri

august 11, 2014

Kuna vahel on hea enda ajule anda koormust rohkem kui 15%, siis mõtlesin võiks jälle OpenCV’ga mängida.
Ausalt öeldes pole C++ väga ammu kasutanud. Mida soovisin teha, oli panna arvuti pildilt auto numbreid otsima, algul tegin palju katsetusi (trial / error development) ja jõudsin sarnasesse punkti, kuhu OpenCV profid. OpenCV pani aju 105% tööle, tuli lausa lisajahutus appi võtta -:)

Millised oleks selle süsteemi rakendused: tulid mõned uitmõtted, ntx sul firmal värav, mis tunneb auto ära ja otsustab – kas see auto lasta automaatväravatest läbi või mitte. Või politseil “background task”, kui patrull ringi sõidab, siis arvuti jooksvalt analüüsib autode numbreid ja teavitab, kas see auto tuleks auto peatada ntx ärandatud / arestitud jne jne.


Leidsin kaks asjalikku algoritmi ja sisuliselt buildisin neist projektidest DLL’id as IS, Delphi’s tegin vaid UI poole:

https://github.com/skandhurkat/CarDetect

https://github.com/MasteringOpenCV/code/tree/master/Chapter5_NumberPlateRecognition

Ka neil algoritmidel omad puudused: paljusid numbreid ei leia, eriti kui autost on pilt tehtud suure nurga all. Parima tulemuse saate, kui autot otse pildistada. Üldiselt algoritmid seal mitmetahulised, aga sisu mõneti sarnane, leia ristküliku taoline kontuur, mille suurus ei ole X ja Y väärtustest suurem. Pildil on numbrilaud alati mingise väikese nurga all, OCR jaoks oleks hea kui see korrigeerida sirgeks. See autonumbri tuvastus pole nii lihtne, kui võiks arvata !

Meie riigiteataja ka abiks: saate teada, millised autonumbri mõõdud Eestis kasutusel:

https://www.riigiteataja.ee/akt/13040616

Mõtlesin, et algul kasutan Harris’e nurkade detektorit, aga autonumbrite omadused ja autode kujud ajavad selle suht sassi. Aga harimise mõttes panen algoritmid, millega leida pildilt nurki ja jooni.

http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=cornerharris#cornerharris

Lühidalt üritan kirjeldada ära nende projektide töö põhimõtet:

* Esmalt teeme pildi mustvalgeks cvtColor

* Järgnevalt eemaldame kerge müra blur(img_gray, img_gray, Size(5,5));

* Siis sooritame Sobel teisenduse.

http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.html

Sisuliselt leiab kohad kus kontuuride värvid muutuvad ja saame kontuuridest sisuliselt mustvalge pildi.


sobel

Järgnevalt Threshold, sisuliselt ütleme, et jäta tähtsamad pikslid alles, Sobel kontuurid on natuke laialivalguvad. Saame kenasti valged kontuurjooned mustal tagataustal.

http://docs.opencv.org/doc/tutorials/imgproc/threshold/threshold.html

threshold

morphologyEx kuidas seda nüüd öeldagi, leia ja ühenda pikslid, mis asuvad lähestikku. Saame regioonid, mida analüüsida (ala kas on ristküliku moodi).

http://docs.opencv.org/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html

close

* Siis findContours abil leiame kõik välised kontuurid: nüüd kus need leitud saame need kanda tagasi olemasolevale pildile.

mask1

Edasine on paras keemia, mida soovitan neist C++ lähtekoodidest lugeda, sisuliselt tuleb analüüsida, kas on ikka ristkülik ja kas seal midagi põnevat sees.

Minu testprogramm teeb cache kataloogi jpeg failid “võimalike” numbritega. Samm, mille võite teha ise, OCR programm peale lasta. Mina soovitan Tesseract-ocr tekstituvastust !

Minu testprogrammi saab siit www.stiigo.com/download/carnumbers.zip

Skype vestlused tekstifaili

juuni 25, 2014

Nagu subjekt ütlebki, oli sellist võimalust vaja. Arvasin, et tegemist elementaarse featurega, aga etskae, polegi sellist varianti (export skype chat to file).

Workarounde oli suht palju, aga enamik olid kahjuks XYZ kaudu hambaravi moodi.

Nii, et tegin ühe programmi, mis teeb vestlustest tekstifailid:

http://www.stiigo.com/download/export_skypechat_history.zip

Delphi: vaatleme klasside uusi võimalusi

august 4, 2011

Nii, nüüd kus olen Delphi XE omanik, pean nentima, et Delphi klasside juures on palju uusi võimalusi tekkinud.
— Võtame koodilõigu ette ja teeme väikese kirjeldamise

program klassid;

{$APPTYPE CONSOLE}

uses
SysUtils;

type

TAclass = class
private
FPorgandid : Integer;
end;

TBclass = class
(* strict private tähendab, et isegi unitis, kus klass paikneb, ei ole võimalik selle klassi muutujat välja kutsuda (klass luuakse create abil samas unitis). Vt allpool näidet *)

strict private
FPorgandid : Integer;
protected

// nüüd ka delphis olemas staatilised muutujad !!

class var FStaatilinemuutuja:integer;
class var FVal : Integer;
// samuti staatilised propertyd !

class functionGetVal: Integer; static;
class procedure SetVal(val: Integer); static;
public

// klasside sees saate nüüd ka konstante hoida !
const Nuudlid = ‘Nuudlid’;
const Hapupiim = ‘Hapupiim’;

// staatiline protseduur, mis kuvab staatilise muutuja väärtust

class procedure kuvaja();
class property val : Integer read GetVal write SetVal;

procedure ytletere;virtual; // tavaline virtuaalne meetod
end;

(* Sealed tähendab, et pärimisahel pannakse kinni TDclassi ei saa enam tuletada klassist TCclass *)
TCclass = class sealed(TBclass)
public

end;

//TDclass = class(TCclass)
// end;

TEclass = class(TBclass)
public
// final välistab järgmise ülekirjeldamise järglasklassis
procedure ytletere;override; final;
end;

(*
TFClass = class(TEclass)
public
procedure ytletere;override; // [DCC Error] klassid.dpr(41): E2352 Cannot override a final method
end;
*)

(*
Struktuur oleks justkui initsialiseeritud “klass”
*)
TStruktuurJustkuiklass = record
Fmuutuja : integer;

public
// struktuuril on constructor…
constructor create(p : Integer); // alati mingit parameetrit vaja
end;

// —————————————

class function TBclass.GetVal: Integer;
begin
result:=FVal;
end;

class procedure TBclass.SetVal(val: Integer);
begin
FVal:=val;
end;

class procedure TBclass.kuvaja();
begin
writeln(self.FStaatilinemuutuja);
end;

procedure TBclass.ytletere;
begin
writeln(‘Tere’);
end;

procedure TEclass.ytletere;
begin
writeln(‘Tere 2’);
end;

constructor TStruktuurJustkuiklass.create;
begin
writeln(‘Initsialiseeriti struktuur TStruktuurJustkuiklass’,p);
end;

// —————————————

(*
procedure TFClass.ytletere;
begin
writeln(‘Tere 3’);
end;
*)

var
pA : TAclass;
pB : TBclass;
pC : TBclass;
pRec : TStruktuurJustkuiklass;
begin
try
pA:=TAclass.Create;
pA.FPorgandid:=123;

pB:=TBclass.Create;
//pB.FPorgandid:=1; (* [DCC Error] klassid.dpr(30): E2361 Cannot access private symbol TBclass.FPorgandid *)

TBclass.FStaatilinemuutuja:=45;
TBclass.kuvaja;

// kutsume välja staatilist propertyd
TBclass.val:=1;
TBclass.val:=TBclass.val+1;
writeln(TBclass.val);

writeln(TBclass.Nuudlid);
writeln(TBclass.Hapupiim);

pRec.Fmuutuja:=45;
pRec:=TStruktuurJustkuiklass.create(45);

readln;

finally
pA.Free;
pB.Free;
end;
end.

Nii sellega lühike ülevaade lõppes…
Järgmine kord üritan kirjutada Generics kasutamisest, “vahendid” mis ikka koodimahtu kõvasti vähendavad.

Delphi 7 toetus Apache 2.0 / 2.2 moodulitele

märts 22, 2011

Ükspäev avastasin, et mõnel firmal ikka raha vist liiga palju 🙂 Võeti Delphi programm ja hakati php’sse üle viima…aus olles mul oli seda raske mõista (raha versus aeg), sest on olemas Apache ja IIS moodulid, mis võimaldavad kenasti olemasolevat koodi taaskasutada (SOA) arhitektuuriks muuta.

Vastus oli, et puudub ju toetus Apache 2.0../2.2.. moodulitele… Ärge laske ennast petta, see 2.0 toetus on Delphis ka väga aegunud…mingi esimene versioon ehk.

Kui Feedreader projekti arendust tegin, siis sai kenasti veebimoodul + php loodud liides ja tulemus kena ning kiire. Veebimoodulil kenasti json / xml väljundid. Apache moodulid on ka kiiremad (st nad juba masinkoodis), kui interpretaator keeled.

Kuidas siis teha muudatus Delphi sourcedes, et need moodulid oleks toetatud:

1)
kustutada järgnevad *.dcu kataloogis
C:\Program Files\Borland\Delphi7\Lib\Debug
– HTTPD2.dcu
– HTTPApp.dcu
2) looge uus veebimoodul Delphis -> New Items -> Web server Application -> Apache 2x Shared Module (DLL).
Salvestage enda veebimoodul ja sulgege Delphi
3) kopeerida fail HTTPD2.pas veebimooduli kataloogi
4) veebimooduli kataloogi luua fail apachechoosever.inc , mille sisuks on
{$define supportApache20}
//{$define supportApache22}

Nende direktiividega saate määrata millist Apache versiooni toetame: 1… versioonidest ma loobusin.

5) nüüd muudke programmi kataloogis olev fail ära diff faili abil, mille saab siit

6) avage Delphi ning enda veebimoodul ja build all….

Kui te kõik õigesti tegite, saate ilma suurema vaevata muuta olemasoleva koodibaasi veebipõhiseks !

————
Minult küsiti ka lihtnäidet, kuidas Apache moodulit paigaldada.

Teie Delphi veebimoodulist tuleb see esimene väärtus exports apache_module name minu_moodul
teine lihtsalt failinimi mille all projekt salvestatud moodulifail.so / .so fail pole midagi enamat, kui ümber nimetatud .dll. Oma projekti algusesse võite kirjutada {$E so}, siis pannakse automaatselt kohe õige laiend
Ps. enda moodul kopeerige Apache modules kataloogi

httpd.conf faili algusesse kirjutage

LoadModule minu_moodul modules/moodulifail.so

Nüüd vaja veel sinna httpd.conf faili lõppu lisada

<Location /minumoodul>
SetHandler moodulifail-handler
Order deny,allow
Deny from all
Allow from 127.0.0.1
Allow from localhost
</Location>

Ja siis väljakutse
http://127.0.0.1/minumoodul

————

Head pusimist teile !

Ingmar

Programmeerimine: DEP aktiivseks

jaanuar 17, 2011

Mis on DEP ?

http://support.microsoft.com/kb/875352/en-us
Data Execution Prevention (DEP) is a set of hardware and software technologies that perform additional checks on memory to help prevent malicious code from running on a system. In Microsoft Windows XP Service Pack 2 (SP2) and Microsoft Windows XP Tablet PC Edition 2005, DEP is enforced by hardware and by software.

The primary benefit of DEP is to help prevent code execution from data pages. Typically, code is not executed from the default heap and the stack. Hardware-enforced DEP detects code that is running from these locations and raises an exception when execution occurs. Software-enforced DEP can help prevent malicious code from taking advantage of exception-handling mechanisms in Windows.

Täiendavaks lugemiseks: Buffer overflow

Samas on dokumenteeritud, et Windows teeb omamoodi hack-in-dosi: failid, mis on pakitud ASPack abil, nendel ei rakendu DEP ! Põhjus lihtne, osade pakkijate töömuster on suht sarnane buffer overflow’le.

Ntx: Firefox on DEP austaja, nii Firefox.exe’l, kui ka plugin-conteiner.exe’l on DEP alati lubatud. Müts maha nende ees !

————
Lisan siia juurde Delphi koodi, mille kirjutasin ühe enda rakenduse tarbeks:

uses
SysUtils,windows,typinfo;

const
PROCESS_DEP_ENABLE = $000000001;
PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION = $00000002;

type
_DEP_SYSTEM_POLICY_TYPE = (
AlwaysOff=0,
AlwaysOn=1,
OptIn=2,
OptOut=3);

type
TSetProcessDEPPolicy = function(dwFlags : dword):LongBool;stdcall;
TGetSystemDEPPolicy = function():_DEP_SYSTEM_POLICY_TYPE;stdcall;
TGetProcessDEPPolicy = function(hProcess : THandle;
var lpFlags : DWord;
var lpPermanent : LongBool):LongBool;stdcall;

var
pSetProcessDEPPolicy : TSetProcessDEPPolicy;
pGetSystemDEPPolicy : TGetSystemDEPPolicy;
pGetProcessDEPPolicy : TGetProcessDEPPolicy;

plib : THandle;
ppol : _DEP_SYSTEM_POLICY_TYPE;
pflags : DWord;
plperm : LongBool;
begin
writeln('Ingmar Tammeväli 2010 http://ingmar.planet.ee');
plib:=getmodulehandle('kernel32.dll');
pSetProcessDEPPolicy:=getprocaddress(plib,'SetProcessDEPPolicy');
pGetProcessDEPPolicy:=getprocaddress(plib,'GetProcessDEPPolicy');
pGetSystemDEPPolicy:=getprocaddress(plib,'GetSystemDEPPolicy');

if assigned(pSetProcessDEPPolicy) and assigned(pGetSystemDEPPolicy) and assigned(pGetProcessDEPPolicy) then
begin
ppol:=pGetSystemDEPPolicy;
pSetProcessDEPPolicy(0);
writeln(typinfo.GetEnumName(TypeInfo(_DEP_SYSTEM_POLICY_TYPE),ord(ppol)));

pflags:=0;
plperm:=false;
pGetProcessDEPPolicy(getcurrentprocess,pflags,plperm);
writeln('protsessi DEP olukord: ',pflags,' ',plperm);

// muul juhul pole seda vaja !
// jonni ikka peale
if (ppol=OptIn) and (pflags=0) then
begin
pSetProcessDEPPolicy(PROCESS_DEP_ENABLE);
// kontroll peale
pflags:=0;
plperm:=false;
pGetProcessDEPPolicy(getcurrentprocess,pflags,plperm);
writeln('protsessi DEP olukord: ',pflags,' ',plperm);
end;

end;

readln;
end.

Programmeerimine: aktiivse veebilehe URL’i küsimine DDE abil

jaanuar 5, 2011

Üldiselt kõik teavad, et DDE’d enam eriti keegi ei kasuta ning DDE oli ka parajalt vigane (ntx DDE serverite numeratsiooni API ise hangus jne). Kuid DDE abil sai isegi Exceliga suhelda, kas nüüd ka enam saab, pole proovinud.

Teada tõde on see, et kui tülikas on erinevatest sirvikutest (Opera/IE/Firefox) urli kätte saada, kord Findwindow trikid, mida kõik veel. IE’ga lihtne, läbi ShellWindowsi….
Mõtlesin, et prooviksin universaalse inimese moodi ja uurin, kas DDE veel elus.

Neid DDE käske toetas kunagi Netscape:

http://graphcomp.com/info/specs/nets/ddeapi.html

Vähemalt üks asjalik DDE request siiani “elus “st vaatasin ntx Firefoxi xul.dll sisse ja nägin seal:

WW_GetWindowInfo
WWW_UnRegisterViewer
WWW_RegisterViewer
WWW_Version
WWW_CancelProgress
WWW_Activate
WWW_OpenURL

Meid huvitab WW_GetWindowInfo

WWW_GetWindowInfo

* Netscape is: Server.
* Transaction Type: XTYP_REQUEST.
* Item (Arguments): dwWindowID
o dwWindowID is the Netscape window to obtain current information on. This value can be 0xFFFFFFFF to specify the last active Netscape window.
* Data (Returns): qcsURL,qcsTitle
o qcsURL is the current URL loaded in the window.
o qcsTitle is the current title of the Netscape window.
* Description: This topic will fail if Netscape can not provide both return values (a blank page is loaded, so there is no URL), or if an invalid dwWindowID is specified.

Siis jõudsin testini: teoorias peaks saama loendada kõiki aknaid järjekorras 1,2,3,4,5… nii need “window” ID’d kunagi jooksid. Testprogramm tõestas vaid, et see kõikide avatud lehtede numeratsioon töötab vaid Operal.

Samas 0xffffffff trikk töötas nii IE’ga, kui Firefoxiga. Ehk kõigist sirvikutest sai teada “aktiivse lehekülje (tabi)”.

Lisan siia lähtekoodi, koos binaryga (download), koodi suhtes pole mõtet kriitikanooli visata, see on mul vist aastast 98 ?

Programmeerimine: vana hea clipboard hook

detsember 9, 2010

Tegemist koodiga, mis koheselt kuvab clipboardi sisu, kui kusagil programmis aka Ctrl+C/kontekstimenüüst valiti Copy. Olin natuke laisk, võtsin näitesse vaid CF_TEXT ja CF_HTML formaadid.


...
procedure TForm1.WMDrawClipboard(var Msg:TMessage);
begin

if FNChain 0 then
SendMessage(FNChain, WM_DrawClipboard, 0, 0);

if Clipbrd.Clipboard.HasFormat(CF_TEXT) or Clipbrd.Clipboard.HasFormat(FCF_HTML) then
Memo1.Lines.Add(Clipbrd.Clipboard.AsText);

end;

procedure TForm1.WMChangeCBChain(var Msg: TMessage);
var
Remove, Next: THandle;
begin
Remove := Msg.WParam;
Next := Msg.LParam;
with Msg do
if FNChain = Remove then
FNChain := Next
else
if FNChain 0 then
SendMessage(FNChain, WM_ChangeCBChain, Remove, Next)
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
FNChain:=SetClipboardViewer(self.Handle);
FCF_HTML:=RegisterClipboardFormat('HTML Format');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
ChangeClipboardChain(self.Handle, FNChain);
end;
...

Lähtekood ja binary siin

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;

Programmeerimine: on mul ikka aega olnud :)

mai 25, 2010

Antud postitus mõeldud rohkem süsteemsete asjadega tegelevatele programmeerijatele 😉

Üldiselt enam Windowsi turvalisusega ei tegele ega tema erinevate API’de testimisega, eriti undocumented, mis olid kunagi ikka väga huvitavad, siis avalikustan osa enda “labview” koode. Koodipuhtust ärge otsige sealt, need “lab” tüüpi koodid on testid, et proovida kuidas erinevad asjad töötavad.

Sealt saab osa C struktuure, mille Delphi‘sse üle viisin:
– _IO_STATUS_BLOCK
– _FILE_INFORMATION_CLASS
– SYSTEM_INFORMATION_CLASS
– UNICODE_STRING
– KWAIT_REASON
– TCLIENT_ID
– THREAD_STATE
– SYSTEM_THREADS
– VM_COUNTERS
– IO_COUNTERS
– SYSTEM_PROCESSES
– SYSTEM_HANDLE_TABLE_ENTRY_INFO
– TUnicodeString
– TObjectNameInformation

Seal testprogrammis on kasutatud: NtQuerySystemInformation API’t, mis oli veel mõni aasta tagasi täiesti dokumenteerimata MS poolt.

Selle api abil (_sysProcesses) kuvab kõik töötavad protessid (CreateToolhelp32Snapshot alternatiiv, kuna viimast troojakad häkkisid).

Teine antud test (_sysHandles) kuvab kõik avatud failid / kataloogid, kus nö pide avatud (handle open) ja pole DenyRead lipuga. Vähemalt WinAmp poolt mängitavat lugu kuvas 🙂 Kuna tegemist testidega ammustest aegadest, siis võib seal olla kalakesi, mis ei näita kõiki faile.
Tegelikkuses on mul seal öeldud, et kuva vaid tüübiga 28 objektid, failid / kataloog. Reaalsuses saaks kõik mutex objektid kätte jne. Kuid PIPE puhul dublicatehandlet tehes programm hangub, see on kerneli tasemel bugi.

Programmis olemas ka APIde kasutus:
NtQueryObject API, sisuliselt selle abil saab pideme(handle) järgi teada, mis on failinimi või mutexi nimi jne, väga hea api
NtQueryInformationFile antud API vaid faili pideme spetsiifiline

adjustPrivileges protseduuris tehtud endale SE_DEBUG_NAME õiguste küsimine.

Siit saate programmi ja lähtekoodid download

Panen ka nö konsool programmi parameetrid:

-p kuvab protsessid
või
-f kuvab avatud failid
-d lisaparameeter, mis kirjutab väljundi programmiga samasse kataloogi dump.log

Tänaseks kõik … järgmises postituses näitan koodi, mille abil saab tuvastada muudatusi programmi IAT tabelis 😉

Koodivaramu: Delphi app. amCharts ja Open Flash Chart

juuni 4, 2009

Üldiselt vaatasin, enamus desktop programme omavad jube igavaid graafikuid. Enamus graafikud meenutavad mulle rastergraafika hiigelaegu. Korraks vajusin mõttesse, viimasel ajal Flash juba suht levinud tehnoloogia, mis peaaegu iga inimese arvutis. Miks mitte rakendada veebis kasutatavaid Flashis tehtud graafikuid desktop programmides !?

Delphis tuleb lihtsalt teha Flash com objekti import + komponendi automaatne loomine ja kogu lugu…

Natuke aega testisin ja proovisin erinevaid koode, algul ei olnud ma eriti edukas, aga hopsti tulid ideed ning sain asjad tööle. Lisan ka screenshotid:

amcharts_ja_delphi

openchartdelphi

Sain kätte ka evendid, et valitud väärtusi kuvada.

Programmide lähtekoodid + binaryd siin (example download)

amCharts on siiski “tasuline”. Tasuta versioonides kuvatakse amcharts linki graafikus

Open Flash Chart on tasuta + LGPL litsensi all, mida veel tahta 🙂

Lihtsalt märkusena võib öelda, et võimaluste poolest on amCharts kobedam, olen teda php projektides kasutanud…
————-
Seniks head pusimist…xor eax, eax…saaks veel normaalse suve ka

Koodivaramu: vilgutame klaviatuuril tulukesi

aprill 10, 2009

Kes DOS aegasid mäletab ja igasugu “naljakaid viirusi”. Tavaliselt ma viirusi naljakaks ei pea , aga see, mis mul ekraanilt tähed alla kukutas oli ikka päris hea (Falling Letters).

Oli ka kunagi Yankee Doodle, see mängis mulle meloodiat ja vilgutas klaviatuuril tulesid vastavalt meloodiale.

Aga 30. aprill on tulekul, mõtlesin proovida, kas Windowsis klaviatuuri tulekesi programmiliselt lihtne vilgutada. Ei näinud küll mingit probleemi. Panin selle suht lihtsa programmikese üles, seal ka binary ja lähtekood.

Saate vähemalt ehk oma naist lollitada, et näe mis juhtub klaviatuuriga, kui liialt kaua msn’is istud 🙂

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

Üks vanem nalja programm
——————-

Naljaviluks

See oli kunagi ühe tuttava soov, sekkub klaviatuuri töösse ja imiteerib hambutu juttu 😉 Kahjuks ma selle lähtekoode enam ei leidnud, suht ammu tehtud.