IMPORTANT! YOU USE THIS SOFTWARE AT YOUR OWN RISK. I AM NOT RESPONSIBLE FOR ANY DATA LOSS THAT MAY OCCUR WHILE USING THIS SOFTWARE. PLEASE READ LICENSE.TXT FOR MORE DETAILED INFORMATION.
WARNING! This software can change executable files of third party vendors. As a result you may violate some license agreements according to which you "may not modify, alter or tamper in any way with the software source code". Please, get acquainted with the license agreements for the programs the files of which you are going to modify.
1. Description
2. The Issue
2.1 Theory
2.2 How It's Done
3. ICP Functioning Principles
4. Using ICP
4.1 Options
4.2 Scanning
4.3 Patching
5. Acknowledgements
7. About The Author
Intel Compiler Patcher (ICP) scans your hard drive for executable files compiled with the Intel C++ Compiler making it possible to disable the CPU dispatcher in detected files, thus, increasing performance of the software that uses these files with CPUs other than Intel.
The compiler or library can make multiple versions of a piece of code, each optimized for a certain processor and instruction set, for example SSE2, SSE3, etc. The system includes a function that detects which type of CPU it is running on and chooses the optimal code path for that CPU. This is called a CPU dispatcher. However, the Intel CPU dispatcher does not only check which instruction set is supported by the CPU, it also checks the vendor ID string. If the vendor string says "GenuineIntel" then it uses the optimal code path. If the CPU is not from Intel then, in most cases, it will run the slowest possible version of the code, even if the CPU is fully compatible with a better version.
The CPU dispatcher function used in Intel compilers is represented by the following piece of code:
[..skip..] mov eax, [ebp][-0008] cmp eax, 0756E6547 ;"uneG" ; Checking on "Genu" jne not_intel ; if it doesn’t equal, switching for not_intel mov eax, [ebp][-0010] cmp eax, 049656E69 ;"Ieni" ; Checking on "ineI" jne not_intel ; doesn’t equal - not_intel mov eax, [ebp][-0014] cmp eax, 06C65746E ;"letn" ; Checking on "ntel" jne not_intel ; doesn’t equal - not_intel mov edx, 000000001 ; the secret byte jmps next not_intel: xor edx, edx ; and here we have 0 for all non-Intel CPUs next: [..skip..]
We can see that the CPU dispatcher checks on "Genu", "ineI", "ntel" and if all checks are successful EDX is given value “1” (one) meaning Intel CPU. Otherwise – “0” (zero) meaning CPU made by any other vendor. Thus, if these checks are disabled or replaced with a condition that is always true in the end EDX register will have ‘1’ (one) regardless of what CPU is actually used.
ICP is based on the algorithm of the original patch utility by M.C. Makey (c) 2004 coded on Perl: an executable file is scanned for compare instructions like 81 fa 47 65 6e 75 (cmp edx, 0756E6547), the latter being replaced by commands like
testl edx, 000000000 (f7 c2 00 00 00 00)Condition
testl edx, 00000000will be always true meaning that EDX will always have value “1” (one) regardless of the string retrieved by CPUID command. Thus, the software will “think” that Intel CPU is used.
These checks on the vendor string can be stored in any CPU register depending on the version of the compiler. ICP checks compare instructions in the following registers:
EAX, EBX, ECX, EDX, EBP, ESI, EDI, and [EBP][offset]
The main GUI window includes the following elements: control buttons, a list of found files, and under it there is an information area that displays information on every found file. Basically, using ICP is a two step procedure:
1) Scanning for files;
2) Disabling the dispatcher in found files (patching).
Options button opens a dialogue where you can configure the following scanning parameters:
Minimal file size – minimal size of the files to be scanned. By default this parameter is set to 500 bytes. This amount can’t be reduced as it’s very unlikely that on Windows you come across an executable file that is less than 500 bytes.
Maximum file size – maximum size of the scanned files. The default value is 100 Mb. Reducing this value will increase scanning speed as ICP loads every ENTIRE file into RAM.
Search for files does not duplicate pairs of registers – this better be explained in detail. Usually the procedure of checking CPU type in Intel compilers assumes three compare instructions to check on "Genu", "ineI", and "ntel" all being in the same CPU register, i.e. only EAX or only EDX etc. However, there are executable files for which checking on the vendor string is made in different CPU registers, for instance:
cmp eax, "Genu"; cmp ebx, "ineI"; cmp edx, "ntel"Such comparison algorithm is usually used only for CPU identification and doesn’t show that the program being checked was compiled with the Intel Compiler. On the other hand, the basic comparison of the Intel CPU dispatcher (comparison with the same CPU register) can go first and further to the end there can be the CPU type check, inserted by a developer. By default this parameter is disabled. It’s not recommended to enable it if you are not completely sure of what you are doing.
Search for files with odd number of matches – the procedure of the Intel CPU comparison in the dispatcher is done by means of three compare instructions. So, for instance, if there is only one comparison instruction in a program -- cmp eax,"Genu" -- this doesn’t mean that this program was compiled with the Intel Compiler. This only means that this is the function of detecting CPU type inserted by a developer. However, like in the previous case there is a possibility that the basic Intel CPU dispatcher check (cmp eax, "Genu"; cmp eax, "ineI"; cmp eax, "ntel") turns out to be in the beginning of the code while a single cmp ebx, "Genu" instruction somewhere in the end. By default this parameter is disabled. It’s not recommended to enable it if you are not completely sure of what you are going to do.
Do backup (.orig) – enables backups of the files to be modified (patched). These files are copied to the same directory where the modified files are and have .orig extension. By default this function is enabled.
File extensions – here you can specify the extensions of the files to be scanned for and patched. By default ICP scans all files that have the following extensions: ".EXE"; ".DLL"; ".ACM"; ".AX"; ".CPL"; ".OCX". Every file extension must begin with a dot (“.”), a semicolon (“;”) must be used as a divider.
Language – the language of the interface.
Auto file list scrolling – automatic scrolling of the file list while scanning. By default this function is enabled.
Enable log file – logging of ICP behaviour. The log file is titled ‘icc_patch.log’ and generated in the same directory from which ICP is launched.
IMPORTANT! It’s recommended to disable your resident antivirus scanner before launching ICP. As ICP works with executable files (reads them and loads them into RAM) resident antivirus scanners intercept any file event and scans them for viruses greatly slowing down ICP scanning. ICP DOES NOT launch executable files that are being read, thus, it can’t activate potential malicious code in your software.
Search button activates scanning for files compiled by the Intel Compiler. Before scanning you will be asked to choose a directory to be scanned. The scanning process is displayed in the status bar at the bottom of the interface. Found files are displayed in the scrollable area. To display file information and detected compare instructions click the name of the file in the file list. You can stop the scanning process by clicking Stop button.
When the scanning is done check the checkboxes that correspond to the needed files and click Patch button.
- This manual includes a part of "Will Intel be forced to remove the "cripple AMD" function from their compiler?" article by Agner Fog.
- Translated into Enlish by Artemy Stepanov (except for the passage from the abovementioned article) e-mail: pplayer1981@gmail.com
- Based on Perl version (C) Copyright M. D Mackey 2004. e-mail: mark@swallowtail.org
Third party libraries:
- TaskEx v1.4 (C) Alexander Alexeev
- AsyncCalls (C) 2006-2009 Andreas Hausladen
- RXLib port (C) Oleg Fedorov
Coded by Tronix (C) 2010. e-mail: tronix286@rambler.ru