zed.0xff.me

раскодируем Trojan.Siggen3.35000

лечение

обнаружение

Попался мне как-то в руки троянчик.
Вот его анализ на pedump.me
Вот так он обнаруживается различными антивирусами:

AntiVir: TR/Offend.6610086.8
BitDefender: Trojan.Generic.6610086
ClamAV: Trojan.Dropper-31300
DrWeb: Trojan.Siggen3.35000
Emsisoft: Trojan.SuspectCRC!IK
F-Secure: Trojan.Generic.6610086
Fortinet: W32/Filecoder.AA
GData: Trojan.Generic.6610086
Ikarus: Trojan.SuspectCRC
K7AntiVirus: Riskware
Kaspersky: UDS:DangerousObject.Multi.Generic
McAfee: Artemis!2A8242105FED
NOD32: Win32/Filecoder.AA
Norman: W32/Malware.WVNX
Panda: Trj/CI.A
TheHacker: Trojan/Filecoder.ab

полный отчет на virustotal.com

анализ

троян портит JPG, DOC, XLS файлы. Обнаружить испорченные файлы можно визуально по следующему куску данных в конце файла:

1
2
3
4
5
6
7
8
9
10
001a2cfb:  34 36 34 36 34 34 33 38  34 36 34 36 34 35 33 31  |4646443846464531|
001a2d0b:  33 32 33 35 34 36 34 36  34 36 34 36 33 30 33 31  |3235464646463031|
001a2d1b:  33 30 33 30 33 30 33 30  33 30 33 30 33 30 33 30  |3030303030303030|
001a2d2b:  33 30 33 30 33 30 33 30  33 30 33 30 33 30 33 30  |3030303030303030|
001a2d3b:  33 30 33 30 33 30 33 30  33 30 33 30 33 30 33 30  |3030303030303030|
001a2d4b:  33 30 33 30 33 30 33 30  33 30 33 30 33 30 33 30  |3030303030303030|
001a2d5b:  33 30 33 30 14 00 00 00  00 fb 2c 1a 00 14 00 04  |3030......,.....|
001a2d6b:  00 00 0f 2d 1a 00 14 00  08 00 00 23 2d 1a 00 14  |...-.......#-...|
001a2d7b:  00 0c 00 00 37 2d 1a 00  14 00 10 00 00 4b 2d 1a  |....7-.......K-.|
001a2d8b:  00 05 

(конкретные данные различны в зависимости от содержимого файла)

результат бинарного сравнения нормального (слева) и испорченного (справа) файла:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
00000000: ff 54
00000001: d8 2f
00000002: ff 54
00000003: e1 38
00000004: 25 7a
00000400: ff 54
00000401: ff 56
00000402: 01 56
00000403: 00 57
00000404: 00 55
00000800: 00 54
00000801: 00 51
00000802: 00 54
00000803: 00 51
00000804: 00 54
00000c00: 00 54
00000c01: 00 51
00000c02: 00 54
00000c03: 00 51
00000c04: 00 54
00001000: 00 54
00001001: 00 51
00001002: 00 54
00001003: 00 51
00001004: 00 54

[!]           168_ok.jpg is  1715451 bytes long
[!]          168_bad.jpg is  1715597 bytes long

фактически троян портит по 5 байт в файле с интервалом в 1024 байта. но не просто портит, а записывает оригинал в конец испорченного файла. вот наглядный вид чего он там понаписал:

1
2
3
4
5
6
001a2d5f:  14  00 00 00 00  fb 2c 1a 00  |......,..|
001a2d68:  14  00 04 00 00  0f 2d 1a 00  |......-..|
001a2d71:  14  00 08 00 00  23 2d 1a 00  |.....#-..|
001a2d7a:  14  00 0c 00 00  37 2d 1a 00  |.....7-..|
001a2d83:  14  00 10 00 00  4b 2d 1a 00  |.....K-..|
001a2d8c:  05         

radare2 0.8.x unnecessary memory zeroing fix

radare2 bug

the bug only appears when debugging 32-bit binary on a 64-bit host

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
diff -r e96275c214b5 libr/io/p/io_ptrace.c
--- a/libr/io/p/io_ptrace.c        Mon Oct 24 04:35:42 2011 +0200
+++ b/libr/io/p/io_ptrace.c        Mon Oct 24 16:48:31 2011 +0300
@@ -34,9 +34,11 @@
 #if __OpenBSD__ || __KFBSD__
 #define debug_read_raw(x,y) ptrace(PTRACE_PEEKTEXT, (pid_t)(x), (caddr_t)(y), 0)
 #define debug_write_raw(x,y,z) ptrace(PTRACE_POKEDATA, (pid_t)(x), (caddr_t)(y), (int)(size_t)(z))
+typedef int ptrace_word;   // int ptrace(int request, pid_t pid, caddr_t addr, int data);
 #else
 #define debug_read_raw(x,y) ptrace(PTRACE_PEEKTEXT, x, y, 0)
 #define debug_write_raw(x,y,z) ptrace(PTRACE_POKEDATA, x, y, z)
+typedef void* ptrace_word; // long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
 #endif
 
 static int debug_os_read_at(int pid, ut32 *buf, int sz, ut64 addr) {
@@ -63,10 +65,11 @@
 }
 
 static int ptrace_write_at(int pid, const ut8 *pbuf, int sz, ut64 addr) {
-        ut32 *buf = (ut32*)pbuf;
-        ut32 words = sz / sizeof (ut32);
-        ut32 last = sz % sizeof (ut32);
-        ut32 x, lr, *at = (ut32*)(size_t)addr;
+        ptrace_word *buf = (ptrace_word*)pbuf;
+        ut32 words = sz / sizeof (ptrace_word);
+        ut32 last = sz % sizeof (ptrace_word);
+        ut32 x, *at = (ptrace_word*)(size_t)addr;
+        ptrace_word lr;
         if (sz<1 || addr==UT64_MAX)
                 return -1;
         for (x=0; x<words; x++)

printing from OSX & iOS to Canon MF-4018 shared via WNDR3700

0. Reason for this all

HP Photosmart 5510

Just bought an HP Photosmart 5510 with wifi & ePrint and my MacBook Air found and installed it via wifi without the need of any drivers or anything.

Canon MF4018

But I also have older Canon MF4018, connected directly to WNDR3700 via usb, and which I failed to set up for printing from my Macs via wifi.

1. Drivers

Netgear WNDR3700

The main reason why I failed is Canon’s drivers for MF4018 (or MF4010, their printing functions are the same). They only have more or less usable drivers for Windows and Linux, closed-source and bad designed, with a lot of proprietary stuff.

There is a way to make your OpenWRT router act like a print server for Windows & Linux clients, but it refuses to work with OSX client.

And even if we’ll somehow force it to work with OSX client, it will still need a lot of Canon drivers installed on Mac and carefully configured. And definitely will not work with iOS

2. Workaround

You can use one simple workaround if you have an x86 or x86_64 computer running 24/7 at your place. Or if you want to manually turn it on every time when you need to print something.

You can then install CUPS on your device, or use a Windows Printer Sharing.

Unacceptable for me. I only have WNDR3700 on ar71xx platform, and AppleTV2 on ARM Cortex A8 running nearly 24/7 at my home.

3. An Insight

If I can’t run an x86 PC 24/7 at my place — who or what can stop me to run it somewhere on Internet?!

(I already have a pair of servers on Internet, so let’s increase their load average a little :)

IMPORTANT: You’ll need to have a Real IP address at your place, or some other way of receiving data from your Internet server, like a SSH tunnel.

4. Step-by-step guide

  1. WNDR3700 (or other OpenWrt-based router, or DD-WRT one, or wl500g)
    1. Connect MF4018 via usb
    2. Set up p910nd
    3. Open port 9100 in firewall:
      iptables -A INPUT -j ACCEPT -p tcp -s your.internet.server.real.ip --dport 9100
  2. Internet server
    1. install CUPS
    2. install Canon Proprietary drivers: for example UFRII/UFRII LT Printer Driver for Linux v2.20
    3. Add a printer:
      lpadmin -p mf4010 -P CNCUPSMF4010ZK.ppd -v socket://my.home.real.ip:9100 -o printer-is-shared=true
    4. enable CUPS Internet sharing:
    5. set up CUPS and/or firewall to only allow connections from YOUR home/office network
  3. Optional steps, needed only for seamless printer autoconfiguration for OSX/iOS devices
    1. Configure
      1. Internet server: use airprint-generate to generate a .service file for your printer
      2. edit generated file: add <host-name>my.internet.server.real.ip</host-name>
      3. WNDR3700: install avahi-daemon, feed it with previously generated file, start it
    2. Now in OSX “Add Printers” Dialog just click “+” and it should see your printer, iOS should see your printer when you’ll try to print some photo

my autogenerated & edited mf4010.service file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0"?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
  <name replace-wildcards="yes">Canon MF4018</name>
  <service>
    <type>_ipp._tcp</type>
    <subtype>_universal._sub._ipp._tcp</subtype>
    <port>631</port>
    <host-name>my.internet.server.real.ip</host-name>       <!-- EDIT THIS -->
    <txt-record>txtvers=1</txt-record>
    <txt-record>qtotal=1</txt-record>
    <txt-record>Transparent=T</txt-record>
    <txt-record>URF=none</txt-record>
    <txt-record>rp=printers/mf4010</txt-record>
    <txt-record>note=laser</txt-record>
    <txt-record>product=(GPL Ghostscript)</txt-record>
    <txt-record>printer-state=3</txt-record>
    <txt-record>printer-type=0x821484</txt-record>
    <txt-record>pdl=application/octet-stream,application/pdf,application/postscript,image/gif,image/jpeg,image/png,image/tiff,text/html,text/plain,application/vnd.cups-banner,application/vnd.cups-postscript,application/vnd.cups-raw,application/vnd.hp-hpgl,image/x-bitmap</txt-record>
  </service>
</service-group>

hack.lu 2011 CTF -- Unknown Planet -- writeup

[ Lobotomy ]

0. original image file

1. analyzing image

all JPEGs have special EOF marker FF D9 and no data must be after this marker.

1
2
3
4
5
[zed@zmac 200.unknown.planet+]#irb -E binary
ruby-1.9.2-p290 :004 > data=File.read '0_8c4f14e28155a2c3cf4b2538c1e0958b.jpg'; data.size
 => 194420 
ruby-1.9.2-p290 :005 > data.split("\xff\xd9").map(&:size)
 => [192405, 2013] 

so, we can see that there’s 2013 spare bytes after EOF marker.

1
2
3
4
5
6
File.open('foo','w'){ |f| f<< data.split("\xff\xd9").last }
 => #<File:foo (closed)> 
ruby-1.9.2-p290 :007 > ^D

[zed@zmac 200.unknown.planet+]#file foo
foo: Zip archive data, at least v2.0 to extract

AHA! It’s a zip! :)

2. unzipping

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[zed@zmac 200.unknown.planet+]#unzip foo 
Archive:  foo
  inflating: 5IIUED7GheR             
  inflating: 6JXtwsTTh9k             
  inflating: 87F1s5POUJc             
  inflating: BPiIOASG_Z6             
  inflating: nLPA8X0UJqf             
  inflating: rySOWi4fZkA             
  inflating: uvlSlG3Tgow             
  inflating: Uw105aD3qYh             
  inflating: Yui5oq58hlx    


[zed@zmac 200.unknown.planet+]#ls -la
-rw-r--r--@  1 zed  staff  20000 Apr 25 16:45 5IIUED7GheR
-rw-r--r--@  1 zed  staff  20000 Apr 25 16:45 6JXtwsTTh9k
-rw-r--r--@  1 zed  staff  20000 Apr 25 16:45 87F1s5POUJc
-rw-r--r--@  1 zed  staff  20000 Apr 25 16:45 BPiIOASG_Z6
-rw-r--r--@  1 zed  staff  20000 Apr 25 16:45 Uw105aD3qYh
-rw-r--r--@  1 zed  staff  20000 Apr 25 16:45 Yui5oq58hlx
-rw-r--r--@  1 zed  staff   1324 Apr 25 16:45 nLPA8X0UJqf
-rw-r--r--@  1 zed  staff  20000 Apr 25 16:45 rySOWi4fZkA
-rw-r--r--@  1 zed  staff  20000 Apr 25 16:45 uvlSlG3Tgow

[zed@zmac 200.unknown.planet+]#file *
5IIUED7GheR: data
6JXtwsTTh9k: data
87F1s5POUJc: 8086 relocatable (Microsoft)
BPiIOASG_Z6: data
Uw105aD3qYh: data
Yui5oq58hlx: data
nLPA8X0UJqf: 8086 relocatable (Microsoft)
rySOWi4fZkA: data
uvlSlG3Tgow: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 8 bit, mono 8000 Hz

Looks like audio file, that was split in chunks of 20000 bytes each.
uvlSlG3Tgow is a first chunk b/c it has a RIFF WAVE header.
nLPA8X0UJqf is a last tail chunk b/c it’s size less than 20000.

3. gluing waves

importing files in Audacity (or any other sound editor) discovers that source file is supposed to be a Morse – coded message. But we must find a correct order of chunks.
So, morse code consists of dots and dashes. Each kind must have fixed length.
We suppose that source file was generated programmatically, not recorder from line or mic. So, it’s timings must be perfect.
Following tool helps to manually find a correct chunks order.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env ruby
STDOUT.sync = true

if ARGV.size == 0
  raise "gimme at least one chunk filename"
end

b0 = "\x80"*8
b1 = "\x27\x01\x27\x80\xd9\xff\xd9\x80"

data = ARGV.map{ |x| File.read(x) }.join.force_encoding('binary')
if data[0,4] == 'RIFF'
  data = data[44..-1]
end

N=120

b0 = b0*N
b1 = b1*N

r = ''
0.step(data.size-1,b0.size) do |i|
  case (d=data[i,b0.size])
  when b0
    print "."
    r << '0'
  when b1
    print "#"
    r << '1'
  else
    raise "SYNC ERROR" if d.size == b0.size
    raise "NOT ENOUGH DATA #{d.size}/#{b0.size}"
    raise "unknown #{d.size} (normal: #{b0.size}) bytes of data #{d.split('').map{|x| "%02x " % x.ord}.join}"
  end
end

calling with a single chunk – script says that it needs more data (more chunks):

1
2
[zed@zmac 1]#./2_manually_guess_chunk_order.rb uvlSlG3Tgow 
##..######..######.../2_manually_guess_chunk_order.rb:32:in `block in <main>': NOT ENOUGH DATA 756/960

calling with wrong 2nd chunk => SYNC ERROR:

1
2
[zed@zmac 1]#./2_manually_guess_chunk_order.rb uvlSlG3Tgow 6JXtwsTTh9k 
##..######..######..###./2_manually_guess_chunk_order.rb:31:in `block in <main>': SYNC ERROR 

two chunks in correct order, script says it needs more chunks:

1
2
[zed@zmac 1]#./2_manually_guess_chunk_order.rb uvlSlG3Tgow 5IIUED7GheR 
##..######..######..##......##..##..##..#./2_manually_guess_chunk_order.rb:32:in `block in <main>': NOT ENOUGH DATA 596/960 

all chunks in correct order:

1
2
[zed@zmac 1]#./2_manually_guess_chunk_order.rb uvlSlG3Tgow 5IIUED7GheR rySOWi4fZkA 87F1s5POUJc 6JXtwsTTh9k Uw105aD3qYh BPiIOASG_Z6 Yui5oq58hlx nLPA8X0UJqf 
##..######..######..##......##..##..##..##......##......##..##......######..##..######......######..##..######..######......######..######..######......##..##..##......

4. decoding Morse

we’ll need a ruby morse gem. install it with “gem install morse

1
2
3
4
5
6
[zed@zmac 200.unknown.planet+]#irb
ruby-1.9.2-p290 :001 > r='##..######..######..##......##..##..##..##......##......##..##......######..##..######......######..##..######..######......######..######..######......##..##..##......'
ruby-1.9.2-p290 :002 > require 'morse'
 => true 
ruby-1.9.2-p290 :005 > puts Morse.decode(r.gsub('......'," ").gsub('######','-').gsub('.','').gsub('##','.'))
PHEIKYOS

Voila! “Pheikyos” is the answer. Case-sensitive.

PS: all source & data files are available at my ctf github repo.

iphone glossy buttons howto

sample images

one big sample image33 individual button images











ObjC code

Following ObjC code uses iphone Private API (UIGlassButton class), so it may be rejected from AppStore.
BUT you can generate a lot of iphone-style glossy button images with it, save to PNG, and use in your projects.

IMPORTANT: this code must be run on iPhone simulator. it saves PNG images to /tmp folder on your computer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#define UIColorFromRGBA(rgbValue,a) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
  green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \
  blue:((float)(rgbValue & 0xFF))/255.0 alpha:a]

Class theClass = NSClassFromString(@"UIGlassButton");

for(int j=0;j<3;j++){
    for(int i=0;i<=10;i++){
        UIButton *theButton = [[[theClass alloc] initWithFrame:CGRectMake(5+120*j, 5+i*44, 120, 44)] autorelease];
        [theButton setValue:UIColorFromRGBA(0xff<<(j*8),0.1*i) forKey:@"tintColor"];
        //[theButton setTitle:@"Accept" forState:UIControlStateNormal];
        [self.view addSubview:theButton];
        
        UIGraphicsBeginImageContext(theButton.frame.size);
        CGContextRef theContext = UIGraphicsGetCurrentContext();
        [theButton.layer renderInContext:theContext];
        
        UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
        NSData *theData = UIImagePNGRepresentation(theImage);
        [theData writeToFile:[NSString stringWithFormat:
                              @"/tmp/btn%@%02i.png",
                              j==0 ? @"B" : (j==1 ? @"G" : @"R"),
                              i] atomically:NO];
        
        UIGraphicsEndImageContext();
    }
}

and now make them stretch

automatically stretching to
(oops, button lost a shadow during screen capture, not important here though)

note that stretchableImageWithLeftCapWidth method:

1
2
3
4
            UIButton* button = [[UIButton alloc] init];
            [button setTitle:@"  looong long long very long text  " forState:UIControlStateNormal];
            [button setBackgroundImage:[[UIImage imageNamed:@"btnB10.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:10] forState:UIControlStateNormal];
            [button sizeToFit];

NB: Don’t forget to release a button ! :)

Наноисследование твиттера :)

1. Очевидный факт – минимальная длина юзернейма в твиттере = 1 символ

примеры: @a @b @0
естественно, на данный момент они уже все давно заняты :)

2. Не всякий @lol это LOL и не всякий @nike это Nike

примеры:

@nike 1K followers 0 tweets ни разу не найк
@adidas 4K followers 170 tweets вроде как адидас
@puma 21K followers 1200 tweets аутентичная пума
@sela 46 followers 4 tweets какой-то мужик
@mcdonalds 163K followers 5500 tweets аутентичный макдак
 
@lol 800 followers 41 tweets совсем не смешно
@humor 1200 followers 13 tweets аналогично
 
@yandex 65K followers 800 tweets аутентичный яндекс
@google 3.5M followers 2800 tweets аутентичный гугл
@apple 2K followers 2 tweets не эппл ни разу

Вывод №1: популярный юзернейм вроде @apple или @humor может принести пару тысяч лишних фолловеров

Вывод №2: что следует сделать твиттеру

Твиттеру следует сделать возможность покупки уже существующих имен. Не принудительной естественно. Просто при заходе в чужой профиль кнопочка “I want to buy this username” и как на ебее – ставки, минимальная цена, аукцион (опционально) и т.п.
А может и сам владелец профиля у себя в настройках выставлять “I would sell this username for at least $5000”.
Соответственно если кто-то на эту кнопочку нажал, и сумму указал, он подтверждает что он не просто так нажал, а этим взял на себя обязательство в случае согласия владельца юзернейма купить его (юзернейм, а не владельца :) за указанную сумму.

Android Alchemy 2.0 new features & elements

Features

  • 10 new elements (380 total)
  • optimizations for tablet devices
  • profiles support
  • workspace contents is now saved between game sessions
  • performance improvements

New elements

chocolate
hot chocolate
e-book
beetroot
borscht
crop circles
woman
mermaid
baby
Transformers

Setting up a scan server on OpenWrt & NetGear WNDR3700

1. Install OpenWrt trunk for ar71xx

Follow openwrt wiki WNDR3700 page for detailed instructions.
I used openwrt-ar71xx-generic-wndr3700-squashfs-factory.img and it worked like a charm. Your firmware image may be different, especially if you have WNDR3700 V2. Read wiki carefully.

Note that trunk build does not have HTTP GUI by default. If you want GUI you have to login with telnet and do:

1
2
3
4
opkg update
opkg install luci
/etc/init.d/uhttpd start
/etc/init.d/uhttpd enable

Or just don’t use trunk. stable branch has the GUI by default.

As for me, I’m happy with CLI (no GUI at all) because it saves precious kilobytes of internal flash (5Mb total is available for user)

2. Configure your wired/wireless networks.

Use HTTP GUI or CLI, see WNDR3700 page or other pages in OpenWrt wiki

2½. [optional] set up extroot

Or you may exhaust all your router free “disk” space very fast.

Or you may be smart enough to fit everything in your router’s default flash memory.

Or your router may have much more that 5Mb of flash available :)

at this step I used a small 2-port unpowered USB hub with integrated microSD card reader + 256Mb microSD card

3. Connect your USB scanner & install USB support packages

1
2
opkg update
opkg install kmod-usb2 usbutils kmod-leds-wndr3700-usb

repeating opkg update is not necessary if you did update before and did not rebooted your device.

Ensure your scanner is visible as USB device (mine is Canon MF4018):

1
2
3
4
root@OpenWrt:~# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 003: ID 04a9:26b4 Canon, Inc. MF4010 series

4. Install SANE frontends & backends

1
opkg install sane-frontends sane-backends

Ensure your scanner is recognized by SANE:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@OpenWrt:~# sane-find-scanner 

  # sane-find-scanner will now attempt to detect your scanner. If the
  # result is different from what you expected, first make sure your
  # scanner is powered up and properly connected to your computer.

  # No SCSI scanners found. If you expected something different, make sure that
  # you have loaded a kernel SCSI driver for your SCSI adapter.
  # Also you need support for SCSI Generic (sg) in your operating system.
  # If using Linux, try "modprobe sg".

found USB scanner (vendor=0x04a9 [Canon Inc.], product=0x26b4 [MF4010]) at libusb:001:003
  # Your USB scanner was (probably) detected. It may or may not be supported by
  # SANE. Try scanimage -L and read the backend's manpage.

  # Not checking for parallel port scanners.

  # Most Scanners connected to the parallel port or other proprietary ports
  # can't be detected by this program.

note that “found USB scanner” string.

Try to scan something:

1
2
3
4
5
6
7
root@OpenWrt:~# scanimage
P6
# SANE data follows
640 877
255

***SKIPPING A LOT OF GARBAGE***

you should see a lot of garbage (raw scan data) on your screen, it can be interrupted with Ctrl+C.

5. Set up HTTP

1
opkg install uhttpd jpeg-tools

now edit /etc/config/uhttpd, especially necessary if you have GUI installed. As for me, I only commented out listening on port 443.

grab small HTML/JS/CGI code from my openwrt-scan-server github repo (free hint: look for “Downloads” button at right ;)
and put it to /www dir on your router.

Note that current OpenWrt repos do not have ImageMagick tools available, so if you want a nice image resolution + file size info – you have to install imagemagick-jpeg package and use my identify binary (only for ar71xx platform, see at bin/ar71xx/identify in my github repo, put it in /usr/bin on your router)

6. Test

Navigate to your router’s address: http://192.168.1.1 (you may have another one).
You should see something like this:


Alchemy is working OK on ...

(listing only iDevices b/c there’s too much Android devices, and Alchemy is working on 99% of them)

iDevice Firmware Status
iPhone4 4.2.1
4.2.8
OK
iPod Touch 3g 4.1
4.2.1
4.3.3
OK
iPhone 3g 4.2.x POSSIBLY FIXED IN v1.1
iPod Touch 2g 4.2.x POSSIBLY FIXED IN v1.1
iPhone 2g 3.1.2
3.1.3
FIXED IN v1.1
update is already on the appstore!

Alchemy for iPhone!

Long waited for, Alchemy for iPhone is finally out!

Links: ★ iTunes Previeworiginal tweet

Screenshots & QR:

IMPORTANT UPDATE:
if you discovered a bug or game is not working for you – please leave a comment with bug description and your phone model + iOS version. Thank you!

UPD2: this video shows how to determine your IOS version

с переездом однако :)

Перетащил блог на ec2+gentoo+ruby19+rails3+nginx.
Чему несказанно рад ^________^
Ну и енку заодно тоже смержнул до последней.
Итого на всё ушло что-то около 2 дней.

good old "fc /b" (byte-by-byte binary files compare) in ruby

Code (save as fc.rb)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/ruby
# simple binary file compare (c) http://zed.0xff.me
# like good old DOS "fc /b"

if ARGV.size < 2
  puts("[!] gimme at least two filenames")
  exit
end

handles = ARGV.map{ |fname| open(fname) }

while !handles.any?(&:eof)
  bytes = handles.map(&:readbyte)
  if bytes.uniq.size > 1
    @diff = true
    printf "%08x:"+" %02x"*handles.size+"\n", handles[0].pos-1, *bytes
  end
end

unless handles.all?(&:eof)
  @diff = true
  puts
  ARGV.each do |fname|
    printf "[!] %20s is %8d bytes long\n", fname, File.size(fname)
  end
end

puts "[.] all files are identical" unless @diff

Sample output

1
2
3
4
5
6
7
8
9
10
11
12
#fc.rb black.png white.png 
0000003e: 00 ff
0000003f: 00 ff
00000040: 00 ff
00000064: 23 92
00000065: 79 0a
00000066: 01 04
00000067: 05 02
00000068: 7f 83
00000069: 83 a9
0000006a: dc c5
0000006b: 13 01

Expecting class path separator ':' before '{' in argument number 1

1
2
BUILD FAILED
/path/to/add-proguard-release.xml:35: Expecting class path separator ':' before '{' in argument number 1

How to fix (method #1)

add following line to your default.properties file:

1
external.libs.dir=libs

How to fix (method #2)

edit add-proguard-release.xml and replace

1
<pathelement path="${external.libs.dir}"/>

with

1
<!--pathelement path="${external.libs.dir}"/-->

Installing Gentoo Linux on Sony Vaio VPC-Z13 // Ставим Gentoo линукс на Sony Vaio VPC-Z13

  1. get the EASEUS Partition Manager Home Edition – it’s free and less than 10M in size
  2. shrink the windows main NTFS partition from 128G downto 70G (for example)
  3. create a new 58G partition on free space. type must be Unformatted, I made a Logical partition.
  4. get the System Rescue CD iso and burn to CD or DVD
  5. boot the laptop from CD you just burnt (use F2 to enter BIOS setup)
  6. get Gentoo’s stage3-amd64 and portage-latest archives
1
2
3
4
5
6
7
8
9
10
# ls -la /dev/mapper
total 0
drwxr-xr-x  2 root root     160 Dec  4 19:12 .
drwxr-xr-x 14 root root    3320 Dec  4 16:12 ..
crw-rw----  1 root root  10, 61 Dec  4 19:12 control
brw-rw----  1 root root 253,  0 Dec  4 19:12 isw_bdfiifejbd_Volume0
brw-rw----  1 root root 253,  2 Dec  4 19:12 isw_bdfiifejbd_Volume01
brw-rw----  1 root root 253,  3 Dec  4 19:12 isw_bdfiifejbd_Volume02
brw-rw----  1 root root 253,  4 Dec  4 19:12 isw_bdfiifejbd_Volume03
brw-rw----  1 root root 253,  5 Dec  4 19:12 isw_bdfiifejbd_Volume05

Volume0 is a whole Vaio’s RAID drive (128G)
Volume01 is a some kind of recovery partition (8G)
Volume02 is a Win7 boot partition (100M)
Volume03 is a 70G C: (NTFS)
Volume05 is a unformatted 58G partition – Gentoo will live here

TBC

Alchemy 1.9 new elements

Australia Австралия
China Китай
clock часы
dog собака
Egypt Египет
Finland Финляндия
France Франция
Germany Германия
Iceland Исландия
India Индия
Italy Италия
Japan Япония
kangaroo кенгуру
kilt килт
Mexico Мексика
planet планета
Romania Румыния
Russia Россия
salo сало
Saudi Arabia Саудовская Аравия
sauna сауна
Scotland Шотландия
swiss army knife швейцарский нож
Switzerland Швейцария
Transylvania Трансильвания
Ukraine Украина
United Kingdom Великобритания
USA США
Venice Венеция
wolf волк

please DO NOT post a lists of elements and/or combinations in the comments below. Thank you!