/* sampopcid.c - What information Sampo Bank extracts from the system build with: gcc -m32 -Wall -O2 -rdynamic sampopcid.c -ldl -o sampopcid You need the following jar uncompressed in the current dir: https://verkkopankki.sampopankki.fi/html/java/GWPKI/SAM/InterfaceWeb.jar (hint: jars are regular zip files) Finally just run the cmd and see the output. $ ./sampopcid As far as I can tell the information is not used as-is, but is rather used as the seed for a SHA-256 IDs. Considering the source material for the ID, it is probably some global system idenfification (it is unique even from behind a NAT, and the ID changes if the system configuration, or OS version does). The Java_dk_danskebank_ec_ec_esafekey_businesslogic_IDFactory_getID is the actual JNI routine generating collection of BASE64 encoded strings that is returned to java side. (C) 2008 Harry Sintonen No warranty. Use at your own risk. Version history 1.0 26.3.2008 initial version 1.1 26.3.2008 reworded title, added note about the SHA-256 stuff 1.2 26.4.2008 added the *getID function call. remove the tmpfile. */ #include #include #include #include #include struct func { const char *name; int type; int maxidx; }; const struct func funcs[] = { {"getUSERId", 0}, {"getCPUId", 0}, {"getMEMId", 0}, {"getPARTId", 0}, {"getKRNLId", 0}, {"getPCIId", 0}, {"getALSAId", 0}, {"getHDId", 1, 3}, {"getMAC", 0}, {"getHOST", 0}, {"Java_dk_danskebank_ec_ec_esafekey_businesslogic_IDFactory_getID", 2}, {NULL, 0} }; typedef void (*f0_t)(char **, int32_t *, char **); typedef void (*f1_t)(char **, int32_t *, char **, int32_t); typedef void (*f2_t)(const void *, void *, void *, void *, void *, void *, void *, void *, void *); static char _p[80] = "/tmp/sampoXXXXXX"; char *path = _p; static char *argfunc(void *ctx, char *str) { return str; } static void resfunc(void *ctx, const char *str) { printf("result \"%s\"\n", str); } static void tmpfilefunc(void *ctx, char *tmpname) { } #pragma pack(4) static const struct foo { int32_t foo[0x29c / 4]; /* here be monsters */ void (*resfunc)(void *, const char *); /* 29c */ int32_t bar[1]; /* 2a0 */ char *(*argfunc)(void *, char *); /* 2a4 */ void (*tmpfilefunc)(void *, char *); /* 2a8 */ } foo = { {0}, resfunc, {0}, argfunc, tmpfilefunc }; static const struct { const struct foo *ptr; } ctx = { &foo }; #pragma pack() int main(void) { int rc = EXIT_FAILURE; void *handle = dlopen("jni/linux/pcid.dll", RTLD_NOW); if (handle) { const struct func *funcptr; if (mkstemp(_p) < 0) { perror("mkstemp"); return rc; } for (funcptr = funcs; funcptr->name; funcptr++) { void *func; func = dlsym(handle, funcptr->name); if (func) { char *str; int32_t rc; char *rcstr; int i; printf("\n%s:\n", funcptr->name); for (i = 0; i <= funcptr->maxidx; i++) { switch (funcptr->type) { case 0: ((f0_t) func) (&str, &rc, &rcstr); break; case 1: ((f1_t) func) (&str, &rc, &rcstr, i); break; /* Note: spoofing /home//e-Safekey/ with /tmp/. Yes, there is a slight security hole here (predictable and unsafe temporary file creation). */ case 2: ((f2_t) func) (&ctx, 0, "/tmp/", "ISO-8859-1", "i386", "Linux", "2.6.24.4", "luser", "Free Software Foundation, Inc."); break; } if (funcptr->type != 2) { if (rc) { printf("result \"%s\"\n", str); } else if (i == 0) { printf("this call failed\n"); } } } } else printf("can't find function %s\n", funcptr->name); } remove(_p); rc = EXIT_SUCCESS; dlclose(handle); } else printf("error \"%s\"\n", dlerror()); return rc; }