My soldering station

I actually never have my own station. I always have been using cheapest soldering iron without any regulator. Of course I has access to such equipment in work, but it’s not the same. And I quit that work lately.

My first attempt to improve my iron was to add a diode serially with heater. It cut out half of the supply sine, so the iron works with the half of its power. I’ve added also a switch parallel with the diode which allow me to use also the full power. That improvement let me to decease power when the bit becomes too hot.

About a week ago I decided to build a real station. I bought an iron (Solomon SL10: 24V, 48W with thermocouple). Most expensive part – transformer I already have, thanks that I’ve saved a lot of money.

Here is the schematic (click to enlarge):


P1 is where you set the temperature, with P2 you could calibrate the device. It could also display temperature using attached panel voltmeter. I’ve selected resistor values to work with digital voltmeter in range of 20.00V (0.01V correspond with 1°C). IC1A amplify voltage from thermocouple to achieve this range. Using S2 you could select which temperature you’d like to measure (real or set).

P1, R1 and R2 makes the temperature range which you could set to about 150-460°C. IC1B works as comparator, it powers up OK1 whenever the amplified voltage from thermocouple is smaller from the voltage from P1. I’ve used this optotriac instead of connecting T1 directly to cancel out the noise generating during heater powers up (MOC3041 have build-in zero detector).

Because my transformer has 2x12V output (not a single 24V) I was able to install power selector switch (S1). I could select heater voltage (12V/24V) by this switch. In practice it turns out to be very useful, especially that I have build such simple regulator without thermocouple compensation. With full power iron gains heat quickly but if I need stable temperature to solder some SMD I could switch to 12V and it is able to hold selected temperature very accurate (it changes +/- 2°C).

Only thing that I want to improve is to change the soldering iron. Solomon SL10 has termocouple too close to the heater. In result the bit temperature is significantly smaller than measured one. But what to expect from 10$ iron.


Q29 noticed that C1 capacitor polarity was reversed, I’ve corrected the schematic.

Porting AutoMapa 6.10 to SIMPad

Yes, I bought new SIMPad – most powerful model SLC.

My last port of AutoMapa is a little bit outdated so I decided to port the new version (6.10B). After changing architecture differences (same as in my previous port) new problem arose – missing function imported from coredll.dll. It is imported by wce24Am.exe by ordinary number (1777). IDA claims that it is EnumDisplaySettings. It appears that this function is never used, but I’m not sure. It returns 0 when fails.

I changed the ordinary number in IAT to 113 (good as any other value exported by coredll.dll) and changed the calling routine to nop instruction. Now it will always return 0.

Unfortunately, AutoMapa developers claims that this is the last version of this product for Windows CE 4.20.

Controlling Samsung TV adjustments

Samsung TV’s (series D and probably series C) are equipped with some feature called Rendering Control Service. It is simply network protocol useful to control some parameters related to audio and video options (e.g. volume level, brightness etc).

Protocol is based on HTTP and XML technology. Requests are sent by TCP port 52235 and looks like:

POST /upnp/control/RenderingControl1 HTTP/1.1
Content-Type: text/xml; charset="utf-8
SOAPACTION: "SoapAction:urn:schemas-upnp-org:service:RenderingControl:1#GetVolume"
Cache-Control: no-cache
Content-Length: 354
Connection: Close

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="" xmlns:s="">
<ns0:GetVolume xmlns:ns0="urn:schemas-upnp-org:service:RenderingControl:1">

SOAPACTION contains action name (GetVolume), rest of this string is constant. Host IP is, of course, our device address. Content-Length define payload data length (XML data). Rest of the headers above is rather self-explanatory.

Header lines are separated by two bytes CR+LF (carriage return 0x0D followed by new line symbol 0x0A). Between headers and payload there is one extra empty line – CR+LF+CR+LF.

XML data is almost entirely predefined constant. Only <ns0:Getvolume …>…</ns0:GetVolume> are customizable. GetVolume is action name and the subtags (InstanceID, Channel) are parameters with determined values. List of all valid actions, values and parameters are covered in My TV does not support every actions defined in here.

TV response  will be similar to request:

HTTP/1.1 200 OK
CONTENT-TYPE: text/xml; charset="utf-8"
DATE: Thu, 01 Jan 1970 03:25:13 GMT
SERVER: Linux/9.0 UPnP/1.0 PROTOTYPE/1.0

<s:Envelope xmlns:s="" s:encodingStyle=""><s:Body><u:GetVolumeResponse xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1"><CurrentVolume>6</CurrentVolume></u:GetVolumeResponse></s:Body></s:Envelope>

I’m sure it require no comment.

We can of course set up parameters too. E.g. it is possible to set volume:

POST /upnp/control/RenderingControl1 HTTP/1.1
Content-Type: text/xml; charset="utf-8
SOAPACTION: "SoapAction:urn:schemas-upnp-org:service:RenderingControl:1#SetVolume"
Cache-Control: no-cache
Content-Length: 389
Connection: Close

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="" xmlns:s="">
<ns0:SetVolume xmlns:ns0="urn:schemas-upnp-org:service:RenderingControl:1">

I plan to release simply C++ classes to control Samsung TV with this protocol, and previously described Samsung Network Remote Control.

Samsung TV network remote control protocol

It happens, that I get my new 32″ Samsung TV – model LE32D550. Like most of new Samsung TV’s (if not everyone) it could be connected into the LAN. Of course, one of the first thing I do when the network cable was connected was port-scan.

C:\Users\Michal>nmap -p 1-65535 tv.lan

Starting Nmap 5.21 ( ) at 2012-02-16 22:19 îrodkowoeuropejski czas stand.
Nmap scan report for tv.lan (
Host is up (0.0016s latency).
Not shown: 65531 closed ports
52235/tcp open  unknown
52396/tcp open  unknown
55000/tcp open  unknown
55001/tcp open  unknown
MAC Address: 60:6B:BD:AB:FC:95 (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 9.04 seconds

55000 is used for remote control over network. There is application for iPhone and Android smartphones (unfortunately only these created by Samsung) to control TV through WiFi. I did some research, and now I understand the protocol quite well.

1. Authentication

When connection on port 55000 is established, remote control must be authenticated. It sends datagram.

0000   00 13 00 69 70 68 6f 6e 65 2e 69 61 70 70 2e 73  ...iphone.iapp.s
0010   61 6d 73 75 6e 67 38 00 64 00 14 00 4d 54 6b 79  amsung8.d...MTky
0020   4c 6a 45 32 4f 43 34 78 4c 6a 45 77 4d 41 3d 3d  LjE2OC4xLjEwMA==
0030   10 00 5a 32 52 7a 4e 7a 4d 30 64 47 64 30 5a 41  ..Z2RzNzM0dGd0ZA
0040   3d 3d 0c 00 63 32 4d 77 64 48 6b 75 63 47 77 3d  ==..c2MwdHkucGw=

And the meaning of this bytes.

offset  value and description
------	---------------------
0x00   	0x00 - datagram type?
0x01	0x0013 - string length (little endian)
0x03	"" - string content
0x16	0x0038 - payload size (little endian)
0x18	payload

I don’t know the meaning of the string above, my TV is accepting any string in here, but I suggest to use this particular one just for compatibility reason.

Payload starts with 2 bytes: 0x64 and 0x00, then comes 3 strings encoded with base64 algorithm. Every string is preceded by 2-bytes field containing encoded string length. These three strings are as follow:

  • remote control device IP,
  • unique ID – value to distinguish controllers,
  • name – it will be displayed as controller name.

TV reply us giving following datagram:

0000    02 0c 00 69 61 70 70 2e 73 61 6d 73 75 6e 67 06
0010    00 0a 00 02 00 00 00                             .......

It means:

offset  value and description
------	---------------------
0x00   	don't know, it it always 0x00 or 0x02
0x01	0x000c - string length (little endian)
0x03	"" - string content
0x0f	0x0006 - payload size (little endian)
0x11	payload

String content is always or Meaning of these strings is unclear, I suggest to not compare it with any specific value during response parsing (maybe other devices using another values).

Payload is one of the following:

  • 0x64, 0x00, 0x01, 0x00 – access granted, you can now send key codes and it will be executed by TV,
  • 0x64, 0x00, 0x00, 0x00 – access denied – user rejected your network remote controller,
  • 0x0A, 0x00, 0x02, 0x00, 0x00, 0x00 – waiting for user to grant or deny access for your app,
  • 0x65, 0x00 – timeout or cancelled by user.
Access is granted only during current TCP connection, when your app or TV disconnect, you have to repeat the authentication process.

 2. Sending key codes

Now you can send simple datagrams containing key codes.

0000    00 13 00 69 70 68 6f 6e 65 2e 69 61 70 70 2e 73  ...iphone.iapp.s
0010    61 6d 73 75 6e 67 11 00 00 00 00 0c 00 53 30 56  amsung.......S0V
0020    5a 58 31 5a 50 54 46 56 51                       ZX1ZPTFVQ

It means:

offset  value and description
------	---------------------
0x00   	always 0x00
0x01	0x0013 - string length (little endian)
0x03	"" - string content
0x16	0x0011 - payload size (little endian)
0x18	payload

And the payload is:

offset  value and description
------	---------------------
0x18   	three 0x00 bytes
0x1b	0x000c - key code size (little endian)
0x1d	key code encoded as base64 string

TV response will be similar to authentication response, but with different payload data. I will not describe this data detailed because I wasn’t investigated it much.

Key codes list is published in SamyGO wiki:

Useful information can be found also in SamyGO Android Remote sources.


Benoit Dumasin created easy to use C++ class (using QT library) able to control Samsung TV:  (he also provided an example QT widget).


Here is Wireshark protocol dissector create by Konstantin Salikhov (Koka58).

MSI Wind – making System Control Manager more likeable

System Control Manager is an MSI software designed to handle keyboard shortcuts with Fn key for Wind netbooks. Since I have Wind U115 with hybrid hard disc (8GB SSD drive for system and 160GB mechanical drive for data which can be turned off due to lower energy consumption) I am forced to use. IMHO it is very unreliable, uncomfortable and unstable piece of software.

Am I really forced to use it? Not if I know assembler 🙂

SCM have 2 main functions: showing the OSD (icons like WiFi turn on/off etc)  and to switch on and off HDD (when I type HDD I mean the mechanical drive to distinguish it from solid state drive – SSD).

What is wrong with SCM? It’s sometimes not loading properly or loading very long. There are inconvenience related to switching the HDD. And it is very ugly. When I using Fn+F10 to switch off the HDD the ugly window shows up and ask me for confirmation. Well, if I wouldn’t be sure that I want to turn that thing off, certainly I wouldn’t press the Fn+F10 right? But even worse is – this window often loose its focus and it shows up not on top. It’s annoying. OK, lets launch IDA Pro.

How does it work?

System Control Manager consist of 3 main files:

  • MGSysCtrl.exe – tray application,
  • MSIService.exe – service that actually do all the magic,
  • MSIWmiAcpi.dll – library that communicate with the service,
  • MGKBHook.dll – library to set the global hook to keyboard.

HDD off confirmation window are enclosed in MGSysCtrl. Interesting functions I’ve found:

set_hdd_off     equ 0x415290    ; BOOL __cdecl set_hdd_off()
set_hdd_on      equ 0x4156D0    ; BOOL __thiscall set_hdd_on(void *this)
set_hdd_state   equ 0x40E330    ; int __cdecl set_hdd_state(bool hdd_on)
show_hdd_window equ 0x415890    ; int __thiscall show_hdd_window(void *this)
endDialog       equ 0x42AF65    ; int __stdcall CDialog::EndDialog(int nResult)

Purpose of first three functions are obvious. Fourth one is called when the window is created. Last function is closing the confirmation window. We can use it to disable the confirmation window and to turn off the HDD without confirmation (just Fn+F10). To do that I’ve created some patch (nasm code):

set_hdd_state    equ 0x40E330
endDialog        equ 0x42AF65


org 0x415890
    mov esi, ecx    ; need this ?
    push 1
    call endDialog

    push 0
    call set_hdd_state
    add esp, 4
    mov eax, 1

It changes show_hdd_window() function to call endDialog() and then set_hdd_state(1). I know it’s ugly solution (creating window and closing it instantly) but I couldn’t manage pretty way to do that. In theory it should be possible to disable function that shows up the window, but I was unable to do that, MSGSysCtrl always crash. My ugly solution is doing its job, and as they say – if it works, don’t touch it.

Now it works much better. But still there are things to improve. I actually consider to write my own app to replace the original SCM. But there is still much to reverse. Or maybe I’ll use original service and dlls to just write my own OSD + HDD controlling program?


Unpacking PKLITE executables

Recently I came across program that was packed (according to PEiD) by PKLITE32 1.1 (PKWARE Inc.). It is an old version of Keil uVision linker. I have been forced to use Keil 3.60 to manage some code for 8051 CPU. The problem was that the evaluation version of Keil restrict us to create up to 2kB machine code. I needed much more.

Reading the output generated by IDE during compilation I realized that the linker is the problem:


Our linker is BL51.exe. We can open it by some PE editor (e.g. by CFF Explorer Suite) we can see some mysterious sections like .pklstb or .relo2. PEiD claims that it is PKWARE32 packer. I couldn’t find any automatic unpacker for that so we have to do it manually.

We can also determine that sections .text and .data are writeable and sections data is not included into exe file. Probably this sections are packed and stored into another section (.pklstb?). Also entrypoint points into .pklstab code. Let’s try disassembling it by IDA.

.pklstb:0048E000 ; =============== S U B R O U T I N E ===============
.pklstb:0048E000                 public start
.pklstb:0048E000 start           proc near
.pklstb:0048E000                 push    offset dword_48E080
.pklstb:0048E005                 push    offset sub_49E01E
.pklstb:0048E00A                 push    0
.pklstb:0048E00F                 call    sub_49E01E
.pklstb:0048E014                 jmp     near ptr byte_410AA3
.pklstb:0048E014 start           endp
.pklstb:0048E014 ; ---------------------------------------------------

Label dword_48E080 points to some incomprehensible data, byte_410AA3 lays into uninitialized .text section. In sub_49E01E there is some code – consisted with loops and many conditional branches. It must be our unpacking routine.

We can also try to search for string (RESTRICTED VERSION WITH) using strings window (Shift + F12). As we can see – there is no such string.

In this point we have 2 options: we can analyse unpacking function to understand how does it work, or we can just run it and let it unpack itself. I choose option 2 – it is much easier and faster choice.

We have to put breakpoint on jmp instruction (this must be entrypoint into unpacked code). Then we just run debugger and wait. When the breakpoint breaks, all data will be unpacked automagically. If we double click on label byte_410AA3, we can see that there is something in .text section now. If we press c key – assembler code shows up. Now we have to dump unpacked sections (I prefer WinHex – it could edit files already loaded into memory), alter it in original file (you can delete .pklstb) and set entrypoint to point into 10AA3 address (its RVA – address in memory subtracted by base address 0x400000).

Now we can find “RESTRICTED VERSION…” string, change one conditional branch and finally – we can compile code greater than 2kB.

Build target 'Target 1'
Program Size: data=43.0 xdata=0 code=3688
"bf" - 0 Error(s), 0 Warning(s).

No, I won’t tell you how to crack Keil 🙂

Porting AutoMapa 6 to SIMPad

About two years ago I bought a Siemens SIMPad tablet. It is an old ARM-based 8,4″ touchscreen device with Windows CE 4.1 on board. It’s not a secret that I get it to play around with – I like vintage hardware like this.

Unfortunately Siemens was never released WinCE 4.2 for his product, last of the 4.x line system which is required for many programs. There is pack of dlls for SIMPad to run some of them (google for simpad fake dlls), also there is program changing PE headers which modify minimum system version required to run. But many programs still cant run. One of them was AutoMapa (for navigation).

I’ve started to investigate what’s the reason – I’ve googled for information. It found out that AutoMapa (wce42Am.exe) is compiled for ARMv5 instruction set with some additional instructions called Thumb mode and SIMPad CPU – StrongARM has only implemented ARMv4 (without Thumb mode). Without sources – sounds impossible. But it is not.

Continuing my investigation I discovered that AutoMapa never gets into Thumb mode – it run in default ARM mode all the time. It do however uses one new instruction:

BX Rx         (hex: 1xFFF2E1)

Rx is one of the registers (R0 – R15). This instruction is described as branch and exchange. It is unconditional branch to the address from Rx register. If bit 0 of the Rx is set, CPU enters in Thumb mode and starts to process instructions in Thumb instruction set from given address. But, as I mentioned before – AutoMapa never goes into Thumb mode, bit 0 of this register is always cleared. We could replace this instruction with some ARMv4 equivalent which could not change execution mode but just jump into location through register. In ARMv4 we have:

MOV PC, Rx    (hex: 0xF0A0E1)

Which moves value from Rx register into program counter. Both instructions are 4-bytes long so I just replaced every occurrence in code section of PE file. I’ve done it by WinHEX replace options because there was too much hit to made it by hand (almost 2000 replaces). In standard ARM mode every instruction is 4-bytes long and must be located at addresses divisible by 4 so if we check only dwords located at proper addresses there is only a little chance to modify something which is not an instruction.

Next thing to do is to modify PE headers. I’ve changed Machine Code entry (offset 0x10C) from “ARM Thumb” (0x01C2) to “ARM” (0x01C0). Required WinCE version is held in Major and Minor Subsystem Version – I’ve changed Minor (offset 0x152) from 20 to 10 (from 4.20 to 4.10).

After replacing file on SIMPad – AutoMapa started up without any trouble. Maybe a little slow, but usable. But it works! Without any crash or error. Unfortunately I have no longer any SIMPad device to take photo, but I start thinking of getting one 🙂