Exetools  

Go Back   Exetools > General > Community Tools

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 07-22-2026, 14:47
Carina0206 Carina0206 is offline
Friend
 
Join Date: Jun 2026
Location: Mars.
Posts: 22
Rept. Given: 0
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 1
Thanks Rcvd at 68 Times in 20 Posts
Carina0206 Reputation: 0
IDA script to fix IAT virtualized/obfuscated by Winlicense/Themida

The each element of IAT obfuscated/virtualized by Themida/Winlicense points to some address of vm code section in run-time.

In older versions of Themida/Winlicense, after goes ahead all arbitrary jmp instructions in this vm code section's context jumped from virtualized IAT, when once ret instruction is executed, the current element value of stack is just final API address.

But in newer versions, it is used more complex context which has only arbitrary jmp instructions but also arbitrary call/ret instructions pairs in virtualized code flow.

That is, after goes ahead all arbitrary jmp instructions and call/ret pairs in this vm code section's context jumped from virtualized IAT, when final un-paired ret instruction is executed, the current element value of stack points to right Win32 API address.

These IDA scripts replace all addresses jumped to vm code section with real Win32 API addresses in IAT virtualized/obfuscated by Themida/Winlicense.

In case of x64 executables :
Code:
// This IDA script fixes virtualized/obfuscated IAT of x64 executable files packed by Winlicense/Themida
auto dest_addr, api_addr, temp;
auto iat_begin, iat_end;
auto vm_begin, vm_end;
auto fp, ret_event;
auto is_exception;

vm_begin =   0x0;  // write starting address of your executable's vm section in here
vm_end =     0x0;  // write ending address of your executable's vm section in here
iat_begin =  0x0;  // write starting address of your executable's IAT in here
iat_end =    0x0;  // write ending address of your executable's IAT in here

fp = fopen("D:\\Your-exe-IAT-fix.log", "w");     // replace your log file name in here

for(dest_addr = iat_begin; dest_addr < iat_end; dest_addr = dest_addr + 8)
{
  temp = get_qword(dest_addr);
  if(temp >= vm_begin && temp < vm_end)
  {
     msg("%x  :  %x  :  ", dest_addr, temp);
     fprintf(fp, "%x  :  %x  :  ", dest_addr, temp);
     jumpto(temp);
     refresh_idaview_anyway();
     rip = temp;
     api_addr = temp;

     while((rip >= vm_begin && rip < vm_end))
     {
        step_until_ret();
        wait_for_next_event(WFNE_SUSP, -1);
        if(ret_event == EXCEPTION)
        {
           is_exception = 1;
           break;
        }
     }
 
     if(is_exception == 1)
       break;
 
     api_addr = rip;
     patch_qword(dest_addr, api_addr);

     msg("fixed  :  %x  :  %s\n", api_addr, get_name(api_addr));
     fprintf(fp, "fixed  :  %x  :  %s\n", api_addr, get_name(api_addr));
  }
}

fclose(fp);

msg("Done.\n");
In case of x86 executables :
Code:
// This IDA script fixes virtualized/obfuscated IAT of x86 executable files packed by Winlicense/Themida
auto dest_addr, api_addr, temp;
auto iat_begin, iat_end;
auto vm_begin, vm_end;
auto fp, ret_event;
auto is_exception;

vm_begin =   0x0;  // write starting address of your executable's vm section in here
vm_end =     0x0;  // write ending address of your executable's vm section in here
iat_begin =  0x0;  // write starting address of your executable's IAT in here
iat_end =    0x0;  // write ending address of your executable's IAT in here

fp = fopen("D:\\Your-exe-IAT-fix.log", "w");     // replace your log file name in here

for(dest_addr = iat_begin; dest_addr < iat_end; dest_addr = dest_addr + 4)
{
  temp = get_dword(dest_addr);
  if(temp >= vm_begin && temp < vm_end)
  {
     msg("%x  :  %x  :  ", dest_addr, temp);
     fprintf(fp, "%x  :  %x  :  ", dest_addr, temp);
     jumpto(temp);
     refresh_idaview_anyway();
     eip = temp;
     api_addr = temp;

     while((eip >= vm_begin && eip < vm_end))
     {
        step_until_ret();
        wait_for_next_event(WFNE_SUSP, -1);
        if(ret_event == EXCEPTION)
        {
            is_exception = 1;
            break;
        }
     }
 
     if(is_exception == 1)
        break;
 
     api_addr = eip;
     patch_dword(dest_addr, api_addr);

     msg("fixed  :  %x  :  %s\n", api_addr, get_name(api_addr));
     fprintf(fp, "fixed  :  %x  :  %s\n", api_addr, get_name(api_addr));
  }
}

fclose(fp);

msg("Done.\n");

Usage :

1. Execute target process fully.
2. Suspend target process and dump process image.
3. Open dumped image and decide both IAT address range and vm code section range in IDA.
4. Attach IDA local debugger to suspended target process.
5. Suspend all threads of target process except for current thread(for avoiding anti-debugger protection).
6. Load above script in IDA and change beginning/ending addresses of IAT and vm code section and your log file name.
7. Execute IDA script, wait for completion of script running and check log files for correctness.
8. Compete dumping and making new IAT by using Scylla.

Last edited by Carina0206; 07-22-2026 at 15:05.
Reply With Quote
The Following User Says Thank You to Carina0206 For This Useful Post:
kernel (07-22-2026)
  #2  
Old 07-22-2026, 16:30
kernel kernel is offline
Friend
 
Join Date: Oct 2023
Posts: 68
Rept. Given: 0
Rept. Rcvd 23 Times in 18 Posts
Thanks Given: 23
Thanks Rcvd at 86 Times in 40 Posts
kernel Reputation: 23
Hi, thank you for the script. First time i see IDA script for fixing IAT. The script looks very simple. Are you sure it works without landing at OEP and fixing OEP or you have to enter OEP manually after fixing IAT? Themida also obfuscates the resources. They also have to be fixed.
Reply With Quote
  #3  
Old 07-22-2026, 18:05
Carina0206 Carina0206 is offline
Friend
 
Join Date: Jun 2026
Location: Mars.
Posts: 22
Rept. Given: 0
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 1
Thanks Rcvd at 68 Times in 20 Posts
Carina0206 Reputation: 0
Quote:
Originally Posted by kernel View Post
Hi, thank you for the script. First time i see IDA script for fixing IAT. The script looks very simple. Are you sure it works without landing at OEP and fixing OEP or you have to enter OEP manually after fixing IAT? Themida also obfuscates the resources. They also have to be fixed.
It doesn't need to fix OEP when dump image and fix IAT in Scylla.
You need to input only correct original IAT starting address and its size.
But if you want to restore dumped image into fully runnable executable, you have to find OEP and fix it in dumped image, and then when eip reached to OEP(by using method to write 2 bytes 0xEB, 0xFE in OEP for infinite looping in OEP) you have to dump image and fix IAT.

And as talking about resource, in most often cases, all resources are recovered after complete all operations in Scylla because all obfuscated resources are fully recovered on memory in run-time.

Last edited by Carina0206; 07-22-2026 at 18:14.
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



All times are GMT +8. The time now is 19:16.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( Since 1998 )