piątek, grudnia 16, 2011

MOF decompilation

Background

So, you have read very nice article about writing new WMI drivers for kernel, you have downloaded and read how to start manual, you have even read very interesting kernel WMI reference on Ubuntu site. And you are so buzzed with good feelings about this all that you push some commands to dump WMI information from DSDT. Then in completely unexpected way you have to face with...

Reality

    97845ED0-4E6D-11DE-8A39-0800200C9A66:
        object_id: BC
        notify_id: 42
        reserved: 43
        instance_count: 1
        flags: 0x2 ACPI_WMI_METHOD 
    466747A0-70EC-11DE-8A39-0800200C9A66:
        object_id: BD
        notify_id: 42
        reserved: 44
        instance_count: 1
        flags: 0x2 ACPI_WMI_METHOD 
    ABBC0F72-8EA1-11D1-00A0-C90629100000:
        object_id: ?
        notify_id: D2
        reserved: 00
        instance_count: 1
        flags: 0x8 ACPI_WMI_EVENT 
    05901221-D566-11D1-B2F0-00A0C9062910:
        object_id: MO
        notify_id: 4D
        reserved: 4F
        instance_count: 1
        flags: 0

What the heck? It is clearly written what is a function, what is and event and what is something else, articles authors tell you about structures from their computers, but they does not tell a word about your machine. There is no function or parameter description, just "there is a GUID, do what you want with that". You are half lucky if you connect to events and are able to collect some data in the field, but when your machine (like mine) require to send some greetings in advance to receive them, then you are in big troubles. There are two ways of dealing with this...

Ninja

Dig through DSDT, observe function calls flow, chop-out parameters and their type, guess, try and guess again. Then, you should sit near the fireplace and tell all of this to your grandchildrens. There is a chance to get crazy in the process, but you are dealing with "The Kernel", you were warned before you have started. To take away risk, I have for you...

Solution


There is a tool in the Windows Driver Development kit, called wmiofck. Which is designed to check mbf (compiled mof file), and to create interface definitions for it. Most of the WMI based DSDT have in them something called WQXX buffers, they are nothing more than compiled mof files. Just dig them out, and save as a binary file (not so complicated if you know some of the script-fu). Call wmiofck tool on this binary file with parameters:

wmiofck.exe -hwmidevs.h -m -u moftable.mbf
in result you will receive very nicely formatted C .h file, where all WMI functions will have the same names as your device manufacturer wanted them to have. Some of them will have comments, all your parameters will be fully described. Sometimes even some constants will be exposed. You don't belive me? See for yourself:

// ASUSManagement - ASUSManagement #define ASUSManagementGuid \ { 0x97845ed0,0x4e6d,0x11de, { 0x8a,0x39,0x08,0x00,0x20,0x0c,0x9a,0x66 } } #if ! (defined(MIDL_PASS)) DEFINE_GUID(ASUSManagement_GUID, \ 0x97845ed0,0x4e6d,0x11de,0x8a,0x39,0x08,0x00,0x20,0x0c,0x9a,0x66); #endif // // Method id definitions for ASUSManagement #define initialize 1128616019 typedef struct _initialize_IN { // ULONG AP_version; #define initialize_IN_AP_version_SIZE sizeof(ULONG) #define initialize_IN_AP_version_ID 1 } initialize_IN, *Pinitialize_IN; #define initialize_IN_SIZE (FIELD_OFFSET(initialize_IN, AP_version) + initialize_IN_AP_version_SIZE) typedef struct _initialize_OUT { // ULONG BIOS_version; #define initialize_OUT_BIOS_version_SIZE sizeof(ULONG) #define initialize_OUT_BIOS_version_ID 2 } initialize_OUT, *Pinitialize_OUT; #define initialize_OUT_SIZE (FIELD_OFFSET(initialize_OUT, BIOS_version) + initialize_OUT_BIOS_version_SIZE)
This is decompiled version of MOF file from the article mentioned in the beginning of this post, first GUID definition is the GUID for a endpoint called ASUSManagement, then you have method id and input/output parameter descriptions. If you are lucky, and your machine manufacturer was not lazy you will have full API for your machine. Served as you like, chilled with some #define on top.

Full version of generated .h file can be grabbed here. It is very good lecture, especially when used as a reference for initial how to.

środa, lipca 27, 2011

Rączka rączkę myje

Prawie pamiętam dzień w którym zaczęło się to szaleństwo. Po koncercie Lata z Radiem w Jarosławiu (w czasach, gdy zdarzało się im jeszcze grywać w "Polsce B") gdy przechadzałem się przez pobojowisko pod sceną zauważyłem zdeptany parasol. Żal mi się go zrobiło, więc odłamaną rączkę zabrałem ze sobą, od tamtego czasu, podczas deszczowych i wietrznych dni wypatruję w koszach na śmieci porzuconych przez właścicieli parasoli. Zabieram ze sobą jedyną nadającą się jeszcze do użycia rzecz - rączkę, wzbogacając tym samym moją kolekcję.

Identyfikacja

Pozyskanie

Eksponat

Wszystkie moje dotychczasowe zdobycze można obejrzeć w serwisie archiweo.pl, gdzie udostępniam je szerszej gawiedzi.

wtorek, lipca 26, 2011

Wpółczynnik Autobusowy Projektu

Współczynnik ten definiuję się jako ilość osób, członków zespołu, którzy muszą wpaść po autobus, by projekt zakończył się porażką. Ten współczynnik powinien być dużo większy od jedności, w sytuacji gdy jest równy jeden należy dokoptować kogoś jeszcze do zespołu.

Takie wynalazki jak dzielona wiedza w wiki mają minimalny wpływ na powyższy współczynnik i zazwyczaj są pomijane w badaniu.

wtorek, czerwca 07, 2011

Chmury


Tutaj powinien byc jakis mdly tekst o tym jaki to swiat jest piekny i cudowny. Daruje go sobie, napisze tylko: ladne chmury, nie?

środa, maja 25, 2011

Może być gorzej

Wszyscy lubimy niezwykłe zwierzęta. Są różne, różniste potwory. Pająki z uśmiechem, palczaki - są też stwory, które są zapowiedzią czegoś o wiele gorszego. Weźmy takiego hipopotama, bydle wielkie i niebezpieczne - odpowiada w końcu za większość przypadków zgonów ludzi zaatakowanych przez zwierzęta w afryce, jednak sama jego nazwa wskazuje, ze jest to zwierzaczek hipotroficzny - karłowaty, mikry. Czekam dnia, w którym odkryty zostanie zaginiony hiperpotam. Jednak zawsze może być gorzej, w tej samej dziurze co hiperpotam pewnie siedzi cała masa innych dziwactw, z których każdy kolejny jeszcze gorszy od poprzedniego: dźwiedź, lopa czy też mrożący krew w żyłach toperz. Strzeżcie się, one tam siedzą i tylko czekają jakby tu wyleźć i kogoś wciąć na kolację.

środa, kwietnia 13, 2011

Zgubiłeś klucze?

Ktoś je znalazł i powiesił, obrosły brudem, jednak nie wróciłeś, nadal wiszą tam gdzie je ktoś zostawił. W szarym, zakurzonym miejscu.

poniedziałek, marca 28, 2011

Naklejki, strumyki, tygrysy, luksusem powiało

Nowa myszka, wysłużona podkładka, pomocna naklejka i leciwy laptop. Powiało luksusem tak mocno, że aż okno musiałem świeżą słomą dopchać, coby mi domowa atmosfera nie uciekła.

czwartek, marca 24, 2011

Timezone aware cron usage

If your whole application environment is working within one particular timezone, then you are a happy man. Sometimes, especially when you are performing synchronizations with partners from different timezones, and those timezones are changing their time basing on the DST rules. This might be a nightmare, when your scheduled task change their execution time back and forth by one hour every time they want. Simply saying: you may adjust those time manually, it is doable, but please, do you want to do this up to four times a year? What a horrible loss of time!
There are two approaches nice and hard, which one is applicable for you? It depends on the cron compilation configuration. Check it by calling:

man 5 crontab
in console. Of course, you know how to configure cron, scroll down up to example, and when you see something like this:

# mail any output to `paul', no matter whose crontab this is MAILTO=paul # CRON_TZ=Japan # run five minutes after midnight, every day 5 0 * * *       $HOME/bin/daily.job >> $HOME/tmp/out 2>&1 # run at 2:15pm on the first of every month -- output mailed to paul 15 14 1 * * $HOME/bin/monthly
Your way is the easy way, change CRON_TZ variable to desired timezone (in which next command will be executed). Timezone may be changed many times inside of one crontab, default timezone is this one from server.

When you are out of luck, and you don't see that crontab supports CRON_TZ  you will have to write your own mini script, which will perform checking not implemented in cron. First, specify desired timezone for your script:

TZ=Japan 0 4,5,6,7 * * *       ~/japan_cron.sh
Determine what are the highest, and the lowest possible differences between server timezone and desired timezone - when each timezone can change time by one hour, maximum difference is two hours, this results in four hour window in which script should be executed.
The last thing which we have to create is the cron script which will be executed at desired hours and will check current time against desired execution time (hard to explain, example next):

#!/bin/bash #0900 if [ `date +'%H%M'` = '0900' ] then         php nine_am_sync.php fi
Script will check time (in desired timezone) and do what it has to be done. This is not very sophisticated, but simple and working solution.

sobota, marca 12, 2011

Kup pan aplikacje!

No i stało się, wepchnąłem swoją pierwszą aplikację do sklepu. Stałem się pełnoprawnym kupczydłem, na tę okazję (w końcu na jednej się nie skończy) utworzyłem specjalną stronę, gdzie jak na razie jest opis tylko jednej, ale będę tę listę sukcesywnie rozszerzał.

Moje aplikacje w AppWorld można obejrzeć tutaj.

czwartek, lutego 17, 2011

UTMU Google Analytics Request Parameter

During creation of backend PHP component to track page views with use Google Analytics without user knowledge I have encountered interesting problem. GIF request contains parameter which seems to be unrelated to page or view parameters. I have analyzed ga.js code and found that this parameter is created basing on table filled with true/false values. Nothing less, nothing more. Only true/false.

Code responsible for creation of utmu parameter basing on this table can be presented in this form (distributed on WTFPL license):

var usage = []; function setUsage(index) { usage[index] = true; }; function getUsage() { var allChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; var temp = []; for (h = 0; h < usage.length; h++) if (usage[h]) { temp[Math.floor(h / 6)] ^= 1 << h % 6; } for (h = 0; h < temp.length; h++) temp[h] = allChars.charAt(temp[h] || 0); return temp.join("") };
It's looks like that above parameter is not required or validated, it is used only for statistical purposes (analytics inside of analytics). List of functions with their codes found in ga.js file:
FunctionCode
_addIgnoredOrganic15
_addIgnoredRef31
_addItem19
_addOrganic14
_addTrans21
_anonymizeIp70
_clearIgnoredOrganic16
_clearIgnoredRef32
_clearOrganic17
_clearXKey72
_clearXValue73
_cookiePathCopy30
_createAsyncTracker33
_createEventTracker74
_createTracker55
_createXObj75
_deleteCustomVar35
_getAccount64
_getAsyncTracker34
_getClientInfo53
_getDetectFlash65
_getDetectTitle56
_getLinkerUrl52
_getLocalGifPath57
_getName58
_getServiceMode59
_getTrackerByName51
_getTracker0
_getVersion60
_getVisitorCustomVar50
_getXKey76
_getXValue77
_initData2
_linkByPost13
_link12
_sendXEvent78
_setAccount3
_setAllowAnchor7
_setAllowHash8
_setAllowLinker11
_setAutoTrackOutbound79
_setCampaignCookieTimeout29
_setCampaignTrack36
_setCampCIdKey37
_setCampContentKey38
_setCampIdKey39
_setCampMediumKey40
_setCampNameKey41
_setCampNOKey42
_setCampSourceKey43
_setCampTermKey44
_setClientInfo66
_setCookiePath9
_setCookiePersistence24
_setCookieTimeout25
_setCustomVar10
_setDetectFlash61
_setDetectTitle62
_setDomainName6
_setHrefExamineLimit80
_setLocalGifPath46
_setLocalRemoteServerMode47
_setLocalServerMode92
_setMaxCustomVariables71
_setNamespace48
_setReferrerOverride49
_setRemoteServerMode63
_setSampleRate45
_setSessionCookieTimeout26
_setSessionTimeout27
_setTrackOutboundSubdomains81
_setTransactionDelim82
_setTrans20
_setVar22
_setVisitorCookieTimeout28
_setXKey83
_setXValue84
_trackEvent4
_trackPageview1
_trackTrans18
_visitCode54

It is important to mention that, like everything else this code is not guaranteed to always work as it has been described by me. Google can change this anytime in the way which fit they needs the best. When it is currently not checked it can be checked against validity in the future.