Hiya,
I guess I've been semi-retired for a while, but I'm back

I've actually been helping a friend learn how to reverse lately and we just went over the details of upx so I decided to have a look at your target. I replied cursorily to your post earlier, but have since downloaded and sucessfully rebuilt upx scrambler. First off, your entry point and IAT are correct. In fact, if you scrambled another target you would have observed that it rebuilt perfectly. It's really just "boiler plate" upx unpacking. Consequently, UPX scrambler itself must have a little trick up its sleeve

You're quite right in saying that it won't run... And as I said earlier, the 2 most likely scenarios are 1) that the program initializes some data in the decryptor which it checks later in the main program or 2) there is a CRC check. Depending on how you look it it, its not really either one of these scenarios or it's a little of both

Did you trace the prog at the OEP to see *why* it fails?
push ebp
code:00405BE9 mov ebp, esp
code:00405BEB add esp, 0FFFFFFF4h
code:00405BEE push ebx
code:00405BEF push esi
code:00405BF0 push edi
code:00405BF1 call sub_0_402988
code:00405BF6 call sub_0_4036BC
code:00405BFB xor eax, eax
code:00405BFD push ebp
code:00405BFE push offset unk_0_405C73
code:00405C03 push dword ptr fs:[eax]
code:00405C06 mov fs:[eax], esp
code:00405C09 call sub_0_4055B4
code:00405C0E call sub_0_4055E4 ;this function fails
code:00405C13 mov ds:dword_0_407738, eax
code:00405C18 cmp ds:dword_0_407738, 0FFFFFFFFh
code:00405C1F jnz short loc_0_405C26
You'll find that the 4th call down fails. My first step was run the packed application and find out what this function *should* return. It returned C000 in the packed app. Patching in C000 as a return value for that function in my unpacked application didn't work and caused subsequent functions to fail so I had to dig a little deeper. You can clearly see in the above code, that the app is saving this value. I wanted to see how many other references to this value there were so I set a bpm on 407738. After SI broke, I traced a little and found that the value was being passed into a call to SetFilePointer as the "distance to move" parameter. This let me know that the C000 value must be a file offset. From the other parameters passed into SetFilePointer, I now had the file handle so I could set a breakpoint on CreateFileA and extract the name of the file that this offset was being calculated for. Sure enough, the file that was being opened was none other than Upx Scrambler itself. I suspected a CRC check. Now with this knowledge, I traced into the call 004055e4 to determine how this offset was being calculated and used.
push ebp
code:004055E5 mov ebp, esp
code:004055E7 add esp, 0FFFFFEA4h
code:004055ED push ebx
code:004055EE push esi
code:004055EF push edi
code:004055F0 xor eax, eax
code:004055F2 mov [ebp+var_15C], eax
code:004055F8 xor eax, eax
code:004055FA push ebp
code:004055FB push offset unk_0_4056CC
code:00405600 push dword ptr fs:[eax]
code:00405603 mov fs:[eax], esp
code:00405606 or edi, 0FFFFFFFFh
code:00405609 mov ds:byte_0_40702B, 0
code:00405610 lea edx, [ebp+var_15C]
code:00405616 xor eax, eax
code:00405618 call sub_0_402578
code:0040561D mov edx, [ebp+var_15C]
code:00405623 lea eax, [ebp+var_14C]
code:00405629 call sub_0_403021
code:0040562E mov edx, 1
code:00405633 lea eax, [ebp+var_14C]
code:00405639 call sub_0_4034B4 ;open upx scrambler
code:0040563E lea eax, [ebp+var_14C]
code:00405644 call sub_0_40320C ;get file size
code:00405649 mov ebx, eax
code:0040564B mov eax, ebx
code:0040564D call sub_0_4023B8 ; allocate buffer
code:00405652 mov esi, eax
code:00405654 push 0
code:00405656 mov edx, esi
code:00405658 mov ecx, ebx
code:0040565A lea eax, [ebp+var_14C]
code:00405660 call sub_0_4030C4 ; app reads itself into buffer
code:00405665 sub ebx, 0Ch
code:00405668 cmp ebx, 0
code:0040566B jl short loc_0_4056A1
code:0040566D
Here you can clearly see that Upx Scrambler opens itself, calculates it's file size, allocates a memory buffer and maps a PE image of itself into memory via a ReadFile call.
code:0040566D lea edx, [ebp+var_158]
code:00405673 lea eax, [esi+ebx]
code:00405676 mov ecx, 0Ch
code:0040567B call sub_0_4024CC
code:00405680 lea eax, [ebp+var_158]
code:00405686 mov edx, offset unk_0_407484
code:0040568B mov ecx, 0Ch
code:00405690 call sub_0_4025D8
code:00405695 jnz short loc_0_40569B
code:00405697 mov edi, ebx
code:00405699 jmp short loc_0_4056A1
code:0040569B ;
---------------------------------------------------------------------------
code:0040569B
code:0040569B loc_0_40569B: ; CODE XREF: sub_0_4055E4+B1j
code:0040569B dec ebx
code:0040569C cmp ebx, 0FFFFFFFFh
code:0040569F jnz short loc_0_40566D
The next loop starts at the end of the file and scans backwards for byte sequence 505f2e40. In the packed application, it will find this sequence at offset c000 and return this value. In the unpacked program, this value will not be found. Looking at this area in more detail you can see that 505f2eo marks the start of a section of data shortly after the import table. Apparently, the function of call 004055E4 is to locate this data and return an offset to it. This data will presumably be accessed and used later on in the program. Interestingly, this data section is not found in our dumped file. Indeed, it is never mapped into memory at all (hence it isn't dumped). Presumably this is because the program is only loaded according to its PE header specification and the import table size stops just above this data. Consequently, this data is in effect "hidden" from being loaded in memory and thus "hidden" from being dumped. Of course, when the original packed program opens itself and reads itself from disk into memory it will copy this data section, and will be able to scan for it's pointer. For the unpacked program which was dumped from memory, this data section simply doesn't exist and the call attempting to locate its offset will fail resulting in the program exiting as we saw happen. Based on this knowledge, you simply need to copy this data section from the packed program into your unpacked .exe. It really doesn't matter where you place it as the program will scan the entire image for it. I placed mine at the end of the new section I created for UPX Scrambler's rebuilt import table.
Well, this got kinda long... Hope its clear...
Cheers,
Clandestiny