Dll entry point
DLL — How to Write
First, we will discuss the issues and the requirements that you should consider while developing your own DLLs.
Types of DLLs
When you load a DLL in an application, two methods of linking let you call the exported DLL functions. The two methods of linking are −
- load-time dynamic linking, and
- run-time dynamic linking.
Load-time dynamic linking
In load-time dynamic linking, an application makes explicit calls to the exported DLL functions like local functions. To use load-time dynamic linking, provide a header (.h) file and an import library (.lib) file, when you compile and link the application. When you do this, the linker will provide the system with the information that is required to load the DLL and resolve the exported DLL function locations at load time.
Runtime dynamic linking
In runtime dynamic linking, an application calls either the LoadLibrary function or the LoadLibraryEx function to load the DLL at runtime. After the DLL is successfully loaded, you use the GetProcAddress function, to obtain the address of the exported DLL function that you want to call. When you use runtime dynamic linking, you do not need an import library file.
The following list describes the application criteria for choosing between load-time dynamic linking and runtime dynamic linking −
Startup performance − If the initial startup performance of the application is important, you should use run-time dynamic linking.
Ease of use − In load-time dynamic linking, the exported DLL functions are like local functions. It helps you call these functions easily.
Application logic − In runtime dynamic linking, an application can branch to load different modules as required. This is important when you develop multiple-language versions.
The DLL Entry Point
When you create a DLL, you can optionally specify an entry point function. The entry point function is called when processes or threads attach themselves to the DLL or detach themselves from the DLL. You can use the entry point function to initialize or destroy data structures as required by the DLL.
Additionally, if the application is multithreaded, you can use thread local storage (TLS) to allocate memory that is private to each thread in the entry point function. The following code is an example of the DLL entry point function.
When the entry point function returns a FALSE value, the application will not start if you are using load-time dynamic linking. If you are using runtime dynamic linking, only the individual DLL will not load.
The entry point function should only perform simple initialization tasks and should not call any other DLL loading or termination functions. For example, in the entry point function, you should not directly or indirectly call the LoadLibrary function or the LoadLibraryEx function. Additionally, you should not call the FreeLibrary function when the process is terminating.
WARNING − In multithreaded applications, make sure that access to the DLL global data is synchronized (thread safe) to avoid possible data corruption. To do this, use TLS to provide unique data for each thread.
Exporting DLL Functions
To export DLL functions, you can either add a function keyword to the exported DLL functions or create a module definition (.def) file that lists the exported DLL functions.
To use a function keyword, you must declare each function that you want to export with the following keyword −
To use exported DLL functions in the application, you must declare each function that you want to import with the following keyword −
Typically, you would use one header file having define statement and an ifdef statement to separate the export statement and the import statement.
You can also use a module definition file to declare exported DLL functions. When you use a module definition file, you do not have to add the function keyword to the exported DLL functions. In the module definition file, you declare the LIBRARY statement and the EXPORTS statement for the DLL. The following code is an example of a definition file.
Write a Sample DLL
In Microsoft Visual C++ 6.0, you can create a DLL by selecting either the Win32 Dynamic-Link Library project type or the MFC AppWizard (dll) project type.
The following code is an example of a DLL that was created in Visual C++ by using the Win32 Dynamic-Link Library project type.
Calling a Sample DLL
The following code is an example of a Win32 Application project that calls the exported DLL function in the SampleDLL DLL.
NOTE − In load-time dynamic linking, you must link the SampleDLL.lib import library that is created when you build the SampleDLL project.
In runtime dynamic linking, you use code that is similar to the following code to call the SampleDLL.dll exported DLL function.
When you compile and link the SampleDLL application, the Windows operating system searches for the SampleDLL DLL in the following locations in this order −
The application folder
The current folder
The Windows system folder (The GetSystemDirectory function returns the path of the Windows system folder).
The Windows folder (The GetWindowsDirectory function returns the path of the Windows folder).
Dll entry point
Answered by:
Question
«When a DLL is loaded using LoadLibrary, existing threads do not call the entry-point function of the newly loaded DLL.»
This is NOT always true — at least in 64 bit Windows, we found that DLLMain is called with DLL_THREAD_ATTACH.
Using this code and any DLL, the DLL’s DllMain() is called first with PROCESS_ATTACH, then THREAD_ATTACH.
- Edited by chksr Thursday, March 3, 2011 2:12 PM formatting error of forum
Answers
I’m not sure I understand this, the doc says:
«Note that a DLL’s entry-point function is called with this value only by threads created after the DLL is loaded by the process. When a DLL is loaded using LoadLibrary, existing threads do not call the entry-point function of the newly loaded DLL.»
You are creating a thread after you load the dll, according to the docs you should get a THREAD_ATTACH. And you get one. What’s the problem?
- Marked as answer by chksr Thursday, March 3, 2011 3:53 PM
All replies
Sorry, I meant «applications compiled for AMD64».
We did not verify whether it’s reproducable in XP/64, but it can be verified easily using Windows 7.
I’m not sure I understand this, the doc says:
«Note that a DLL’s entry-point function is called with this value only by threads created after the DLL is loaded by the process. When a DLL is loaded using LoadLibrary, existing threads do not call the entry-point function of the newly loaded DLL.»
You are creating a thread after you load the dll, according to the docs you should get a THREAD_ATTACH. And you get one. What’s the problem?
- Marked as answer by chksr Thursday, March 3, 2011 3:53 PM
I’m not sure I understand this, the doc says:
«Note that a DLL’s entry-point function is called with this value only by threads created after the DLL is loaded by the process. When a DLL is loaded using LoadLibrary, existing threads do not call the entry-point function of the newly loaded DLL.»
You are creating a thread after you load the dll, according to the docs you should get a THREAD_ATTACH. And you get one. What’s the problem?
Correct. DllMain with DLL_THEAD_ATTACH is not called for any already running threads.
It will be called for any new threads created after the dll is loaded.
Intercepting DLL libraries calls. API hooking in practice
- Intro
- API Hooking
- DLL Forwarding
- Function calling conventions
- API hooking example
- DLL Proxy
- Summary
- References
- About the Author
Article was published in Programista 03/2013 (10) magazine
API hooking methods for programmers by using DLL libraries forwarding mechanism (DLL proxy).
Sometimes we need to intercept certain DLL library calls, we might discovered an application bug or we want to add an extra feature to the application or to log the invoked functions and its parameters. In normal conditions we have access to the source codes and function modification is just a matter of source code editing, but sometimes we just don’t have access to the source code of the library or the software, like in many cases isn’t distributed with the source code. What to do in this case? In this article you can read about popular API hooking solutions, and there will be presented slightly different approach to this topic.
API Hooking
The most common solution that probably most of you know is called API Hooking, a technique which consists in the fact that the libraries function calls redirect to your code. Most popular API hooking libraries are Microsoft Detours (usef frequently for game hacks), but the price tag on this commercial library is set to 9,999.95 USD (around 31737 PLN!), for Delphi we can find madCodeHook library, its price is € 349 for commercial usage. Beside mentioned libraries, there are many other and free libraries.
API hooking for loaded DLL libraries and their functions works by patching (overwriting) first bytes of the function prologue code we want to hook with a JMP NEAR instruction to our code, encoded in hex as E9 xx xx xx xx ). It looks like this:
Image 1. Function before and after setting the hook.
After the control is passed back to our function, usually we can run our own code, run the original function and return back to the code that invoked the original function from the DLL library.
API Hooking can cause several problems, it’s all related to the structure of the compiled applications and the structure of its code, problem occurs when we would like to invoke original function from the hook itself (usually this would end as an infinite loop), in those cases it’s necessary to create a special code chunk aka trampoline that allows to invoke original function code, despite the hook itself in the function body.
API Hooking technique is practically impossible to use in case of protected DLL libraries, when every change to the library code on the disk or in the memory is not possible when for example CRC checks are present etc.
Classic API Hooking is also not suitable for intercepting pseudofunctions exported by the DLL libraries, I’m talking about exported variables, class pointers etc., because in this type of exports there’s no way to create a classic code hook between the original function and our intercepting code (there’s no function to hook at all). This kind of problems can be solved with PE (Portable Executable) export table modification, but its less popular solution and very few hooking libraries even supports it.
DLL Forwarding
One of the creative and more troublesome ways of API hooking in DLL libraries is using internal Windows mechanism called DLL Forwarding, basically it means forwarding DLL calls to another module.
This technique is based on using replacement library, so called proxy DLL, it exports all of the original library functions and passes all of the calls to the original library except for the functions we want to hook. Function calls are passed to the original library by using barely known Windows mechanism, that lets to use other library functions like they were stored in the hooking library, but in fact their code is located in other library, that’s why the name DLL forwarding — from forwarding, redirection.
Function calling convention
Function calling convention is a low level way of passing parameters to the functions and stack handling mechanism before the function return. Mostly it depends on the compiler settings and in most of the high level programming languages it’s possible to change the calling convention to whatever you want, either by changing the compiler settings or by using special programming language constructs (pragmas etc.). In order for our hooking library to work correctly, its hooking functions has to use the same calling convention as the hooked functions, they just have to be binary compatible in other case it might end with an exception caused by stack damage etc.
Table 1. Function calling conventions.
Calling conventions highly depends on the compiler default settings, and for example Delphi uses register calling convention by default, for the C programming language cdecl is the default calling convention.
WinApi functions (Windows system functions) uses stdcall calling convention, so before the call, the parameters are stored on the stack using push instructions, then the call instruction is executed, after the call there’s no need to correct the stack pointer ESP , because in stdcall convention the stack is automatically corrected just before the function returns. It’s interesting that some of the WinApi functions aren’t using stdcall calling convention but the cdecl, where the parameters are stored on the stack, but the stack correction has to be done after the call by the compiler, based on the number of the parameters passed to the function. One function that uses this convention is wsprintfA() from the Windows system library USER32.dll (its counterpart in C libraries is sprintf() ), this way of calling functions was probably introduced, because it’s impossible to tell how many parameters were actually used by the function itself (only compiler knows this).
API hooking example
As an example we are going to use our test library BlackBox.dll, it exports only two, sample functions Sum() and Divide() , as you can guess the first function adds two numbers and the second function divides two numbers. Lets assume we have a full documentation of this library and we know what the calling convention is used for those two functions (assume we have header files for this library) and we know what parameters are used. In other cases we would have to use reverse engineering to obtain this kind of low level information.
Listing 1. Functions description from BlackBox.dll library
In our example library, the Divide() function is buggy, and dividing by zero causes an exception and our application crashes (lets assume our application doesn’t handle exception handling). Our goal is to fix this problem.
Proxy DLL
To fix the buggy function in BlackBox.dll library, we’re going to create intermediary library, with valid Divide() function implemented, that can handle division by zero without causing an exception. Implementation will be coded using 32 bit assembler, using FASM compiler (polish assembler compiler, created by mr Tomasza Grysztar). Below you will find sample library template with precise code structures comments.
Listing 2. Beginning of our library.
Here you can find output file declaration type, at the beginning of the source code also header files can be placed as well as the name of the entry point function for the DLL library.
Listing 3. Uninitialized data section
Executable files as well as DLL libraries are divided in sections, one of them is a section with uninitialized data, it doesn’t take any space on the disk, but only holds the information about the total size of the uninitialized variables application is using. Section names in executable files doesn’t matter (it’s only limited to 8 chars), usually contractual names are used and in the section declaration access rights has to be defined (read, write, executable), but in FASM compiler case .bss section declaration, creates an uninitialized section for the variables.
Listing 4. Data section
Here we have a name of the original library, that was renamed to BlackBox_org.dll (it’s stored in the source code in ASCIIz format, null terminated), it’s going to be used in the further code so it can be loaded.
Listing 5. Code section with DLL entry point.
Code section contains all of the library functions and the DLL entrypoint function, this is a special function that is called by the Windows operating system, after the library is loaded. Code section has to be marked with executable flags, this is an information to the operating system, that this memory area contains the executable code, if it wasn’t marked as executable any code execution attempt from this memory area would end up as an exception on the CPU processors with DEP (Data Execution Prevention) memory protection mechanism. Inside the initialization function (DllMain), after receiving the DLL_PROCESS_ATTACH event we are using original DLL library name to get its handle, so called HMODULE (so it can be used later on to call the original functions etc.).
Listing 6. Over-optimalization protection
Our library uses the original library, but if we don’t put any reference to it in the source code, FASM compiler will remove any reference to it (optimization) and it won’t be automatically loaded, that’s why here we put a fake call to any of its function, directly after the ret instruction (so it won’t be executed at any point).
Listing 7. Valid Divide() function code
Our Divide() function implementation checks for the division by zero condition and if the divisor is set to zero, function returns the error code FALSE , additionally the pointer to the result variable is extra checked for NULL values and if its an empty pointer, error code is returned as well. Also please notice the calling convention of the function is exactly the same as the calling convention used by the original function, and in our case stdcall convention is used, so the parameters are passed on the stack, function return value is stored in the EAX register
and the stack pointer is automatically corrected, FASM compiler does this automatically, generating ret (number_of_parameters * 4) instruction from the single ret statement in the source code.
Listing 8. Import table of our library.
FASM compiler lets us manually define libraries and functions used by our library, beside standard system libraries, we need to add here a reference to the original BlackBox_org.dll library. Thanks to this, Windows while loading our hooking library will also load the original library in our address space and we won’t have to manually load the original library with the LoadLibraryA() function call. In some cases it’s even mandatory to load library using import table entry, it’s required for dynamic link libraries that uses TLS (Thread Local Storage) mechanism used by multithreaded applications.
Listing 9. Exported functions table
In this section we must declare all of the functions from the original library, functions that we want to hook must be implemented in the code, functions that we want to pass to the original library are stored in a special text format:
for the ordinal exported function, not by the name. All of the inner working of this mechanism is handled by the Windows itself, thus DLL Forwarding.
Listing 10. Relocation section
Last section in our library is the relocation section, it’s required for proper working of our library. It’s because dynamic DLL libraries can be loaded in various base address spaces by the Windows and absolute addresses used for pointers and assembler instruction using absolute addresses has to be updated accordingly to the current base address in the memory and this information is generated in the relocation section by the compiler.
Summary
This API hooking method can be used with success to modify any application that uses dynamic DLL libraries for their working. It has its pros and cons (in relate to the classic API Hookingu methods), but in my opinion it opens much wider space for experiments and offers much easier way of changing complete functionality of the application. Implementation of this method can also be done in high level programming languages with proper usage of the export functions definition files (DEF).
Что делать при ошибке «Точка входа в процедуру не найдена в библиотеке DLL ADVAPI32.dll»
Такая ошибка чаще всего появляется на компьютерах, которые работают под управлением Windows XP. Дело в том, что система обращается к процедуре, которая в этой версии Виндовс отсутствует, из-за чего и происходит сбой. Впрочем, эту проблему можно встретить и на более новых версиях редмондской ОС, где он появляется из-за устаревшей версии, указанной в ошибке динамической библиотеки.
Решения данной проблемы зависят от версии вашей Windows. Пользователям XP, в первую очередь, стоит переустановить игру или программу, запуск которой заставляет ошибку появляться. Пользователям Windows Vista и новее, вдобавок к этому, поможет еще и замена библиотеки.
Способ 1: Помещение ADVAPI32.dll в системную папку
Универсальный способ исправления ошибок доступа к ADVAPI32.dll – отдельная загрузка этой библиотеки и ручной перенос её в определенную системную папку. Переносить или копировать можно любым удобным путем, подойдет и простое перетаскивание из каталога в каталог.
Обращаем ваше внимание на то, что местоположение искомой директории также зависит от версии ОС. Об этом и подобных важных нюансах лучше почитать в статье, посвященной установке DLL-файлов вручную.
Чаще всего обычного перетаскивания недостаточно: библиотека в полагающемся месте, но ошибка продолжает появляться. В этом случае есть необходимость внести DLL в системный реестр. Манипуляция несложная, но определенный навык для неё все-таки нужен.
Способ 2: Переустановка программы или игры
Возможно, что какой-то проблемный элемент в стороннем ПО вызывает сбой, пытаясь получить доступ к библиотеке ADVAPI32.dll. В данном случае рациональным будет попытаться переустановить софт, который вызывает неполадку. Кроме того, это единственный гарантированно рабочий метод борьбы с такой ошибкой на Windows XP, но есть небольшое исключение — возможно, для этой Виндовс понадобится установить не самую новую, а более старую версию игры или приложения.
Некоторые игры, поддерживаемые на Win XP, могут иметь в своем DLC, несовместимую с этой версией ОС. В такой ситуации необходимо искать игру без дополнений.
- Удалите ПО одним из описанных способов в соответствующей статье.
- Шаг только для пользователей XP – очистите реестр, процедура описана в этом материале.
- Инсталлируйте нужное ПО заново, по необходимости самый новый релиз (Vista и старше) или более старую версию (XP).
Иногда стоит искать проблему не в операционной системе, а в программе: пиратский софт часто страдает от ошибок подобного рода, и тогда переустанавливать нужно его.
Способ 3: Удаление обновлений
Иногда случается, что виной ошибке системное обновление KBXXXXXXX, где вместо X — цифры. Нужно попытаться удалить последнее системное обновление или поискать в интернете информацию, какой именно апдейт влияет на появление данной ошибки. Как выполнить деинсталляцию обновления, мы рассказывали в Способе 1 и Способе 2 статьи по ссылке ниже.
Способ 4: Использование точки восстановления
Если проблемы возникли не так давно, а с удалением обновления возникли трудности (например, не удается понять, что именно нужно удалить), можно вернуть компьютер к состоянию, в котором он находился ранее. При включенной функции восстановления системы и наличии точек восстановления с этой процедурой легко справится любой пользователь. Так как эта ошибка появляется на старых ОС, то ниже мы приложим ссылки на инструкции только лишь для них.
Подробнее: Как восстановить Windows XP / Windows 7
Способ 5: Установка обновлений
Кардинально противоположным третьему способу по своей направленности станет этот совет. Иногда проблема, рассматриваемая в этой статье, наблюдается только лишь на определенных обновлениях. Возможно, вам нужно установить последние обновления, если ранее этого почему-то не было сделано. По отзывам некоторых пользователей исправить неполадку с DLL помогает именно это действие.
Способ 6: Переустановка/апгрейд ОС
Далеко не всегда пользователи работают с лицензионными версиями ОС, предпочитая скачивать пиратские сборки, да еще и репаки от умельцев. Некоторые из них могут работать некорректно, и если вам не посчастливилось стать обладателем «кривой» сборки, проще всего будет переустановить ее на приближенную к чистой, а не заниматься решением многочисленных проблем. Если же сборка нормальная и виновата программа, которая не работает корректно на этой версии ОС, нет ничего лучше, чем обновиться до более свежей Windows, обладающей улучшенной совместимостью с софтом.
Перечисленные рекомендации при правильном соблюдении должны помочь вам справиться с возникшей проблемой без особого труда.
Отблагодарите автора, поделитесь статьей в социальных сетях.
How To Fix вЂentry point not found’ errors in Windows
Posted By Jamie on July 11, 2019
The Windows operating system and the software that runs on it has come a long way in terms of usability and reliability, but that doesn’t stop it from throwing a spanner in the works occasionally, though.
I was working on a client computer the other day that kept throwing up an ‘entry point not found’ error. It is apparently a very common error, so I thought I would write a post showing you how to fix ‘entry point not found’ errors in Windows.
But first, we’ll get into a bit of background on the “entry point not found” error.
Software entry points
A software entry point is a point in a software program that hands-off control of the process from the operating system to the application in question.
For example, if you are using Windows 10 and open your web browser, the entry point is when the browser is fully loaded and in full screen, meaning all resources are directed at the browser and not at Windows. In order for this to happen, Windows must successfully make the hand-off to the application, a web browser in this example.
If an entry point is not found, it means the file necessary to hand off that process is damaged, unreadable, or missing.
If you are lucky, the syntax of the error message itself will tell you the exact file that is missing. All you need to do is replace that file or reinstall the program in question, and you’ll solve the entry point problem.
For example, the error syntax might read ‘The procedure entry point FILENAME could not be located in the dynamic link library msvcrt.dll’ when opening a program on Windows. Or, the error message syntax might be something like, ‘The procedure entry point xmlTextReaderConstName could not be located in the dynamic link library libxml2.dll’.
In both examples, the application you are trying to open cannot find a DLL file: ‘msvcrt.dll’ in the first example and ‘libxml2.dll’ in the second.
A DLL file is a Dynamic Link Library file. This is a shared resource that any installed program on a Windows computer can use. Rather than install a copy in each program folder, Windows uses a shared library of common files to save space and make the OS more efficient.
If anything happens to one of these files, any program that needs it to function will throw up an error. Fortunately, this kind of problem is quite straightforward to fix.
Fix ‘entry point not found’ errors in Windows
There are a couple of ways to address ‘entry point not found’ errors in Windows. You can manually locate and install the DLL file in question.
You can install the program that includes the file, or the program calling the file. Or you can perform a System File Check and have Windows correct the error.
All of these methods will work just as well. There is no ‘best’ fix, just the fix you are most comfortable with. If you don’t know what program installs a file, you may be best reinstalling that program or running System File Check.
For example, I know that msvcrt.dll is part of the Visual C++ 2005 Redistributable Package for (X86) because I have over twenty years’ experience working with Windows computers. You may not have the same experience, so using SFC may work best.
One word of caution, though. If you Google ‘missing DLL file’ or words to that effect, you will come across hundreds of websites offering free downloads of these files. Just don’t. It’s a bad idea and the odds are high that it won’t go well for you.
Even if some of them are legitimate, not all of them are going to be, and some are known to deliver malware. If you value your system security, reinstall the program or run SFC instead.
System File Check
System File Check is a built-in Windows utility that scans the OS installation for missing or corrupt files.
Windows contains a database of what files should be there and SFC compares what it finds to what it should find. If there is a mismatch, the utility will obtain a fresh copy of the file and replace it.
Follow these steps to run a System File Check on your Windows machine:
- Open a CMD window as an administrator. (right-click the Windows start button and select Command Prompt (Admin)).
- Type ‘SFC /scannow’ and hit Enter.
- Allow the process time to complete.
If the scan finds a file mismatch or errors, it will automatically fix the issue. If the scan doesn’t find anything wrong, it will tell you so. Then you will need to try one of these other steps.
Manually install the DLL file
If you can identify the missing or damaged file, you can often find a copy in another program and copy it across.
This can be a quick and dirty fix if you need the program to be working in a hurry. Use Windows Explorer and perform a search for the file in question.
Install the program that includes the file
As I said in the example above, msvcrt.dll is part of the Visual C++ 2005 Redistributable Package for (X86). Therefore, to replace the file, I can download the Visual C++ 2005 Redistributable Package directly from the Microsoft website.
If you can identify the exact DLL file referenced in the error message syntax, you can do the same as long as the source of the file is trustworthy. Trustworthy, in this context, means from Microsoft or another trusted source.
Reinstall the program throwing the error
If one particular program is constantly throwing up the ‘entry point not found’ error, it might be easiest to just reinstall that program entirely. Sometimes a fresh install is the best solution for entry point errors and other errors.
As long as you have the installer file or the disc, simply reinstall or select Repair from the installer menu to scan and replace the damaged or missing file. If you overlay the program, you should not lose any functionality or data.
Once again, there’s no ‘best’ fix, there’s just the fix you’re the most comfortable with and that works for you.
Once you decide which fix is the best for you, you’ll be able to fix entry point errors on Windows easily, enabling you to get back up and running at full capacity very quickly.
If you found this article on resolving entry point not found errors useful, then you might also find other TechJunkie how-to articles helpful for resolving Windows errors, including How to fix ‘Windows cannot access computer’ error code 0x80004005 and How To Fix ‘RPC Server is Unavailable’ Error in Windows.
Have you encountered ‘entry point not found’ error messages in Windows before? If so, how did you handle the problem? What was the outcome of your troubleshooting efforts? Please tell us about it in a comment below!