what program is supposed to be associated with dll

Microsoft's implementation of the shared library concept in Windows and Bone/two

Dynamic link library
DLL Icon (PNG).png
Filename extension

.dll

Internet media type

application/vnd.microsoft.portable-executable

Uniform Type Identifier (UTI) com.microsoft.windows-dynamic-link-library
Magic number MZ
Developed by Microsoft
Container for Shared library

Dynamic-link library (DLL) is Microsoft's implementation of the shared library concept in the Microsoft Windows and Os/2 operating systems. These libraries usually have the file extension DLL, OCX (for libraries containing ActiveX controls), or DRV (for legacy organization drivers). The file formats for DLLs are the same as for Windows EXE files – that is, Portable Executable (PE) for 32-chip and 64-bit Windows, and New Executable (NE) for sixteen-scrap Windows. As with EXEs, DLLs tin contain lawmaking, data, and resources, in any combination.

Data files with the aforementioned file format every bit a DLL, but with different file extensions and mayhap containing but resources sections, can be called resources DLLs. Examples of such DLLs include icon libraries, sometimes having the extension ICL, and font files, having the extensions FON and FOT.[1]

Background [edit]

The offset versions of Microsoft Windows ran programs together in a single address space. Every program was meant to co-operate by yielding the CPU to other programs then that the graphical user interface (GUI) could multitask and be maximally responsive. All operating-system level operations were provided by the underlying operating system: MS-DOS. All higher-level services were provided by Windows Libraries "Dynamic Link Library". The Drawing API, Graphics Device Interface (GDI), was implemented in a DLL chosen GDI.EXE, the user interface in USER.EXE. These extra layers on top of DOS had to be shared across all running Windows programs, not just to enable Windows to work in a machine with less than a megabyte of RAM, but to enable the programs to co-operate with each other. The code in GDI needed to translate drawing commands to operations on specific devices. On the display, it had to manipulate pixels in the frame buffer. When cartoon to a printer, the API calls had to exist transformed into requests to a printer. Although it could have been possible to provide hard-coded support for a express gear up of devices (like the Colour Graphics Adapter display, the HP LaserJet Printer Command Language), Microsoft chose a dissimilar approach. GDI would work by loading unlike pieces of code, chosen "device drivers", to work with different output devices.

The same architectural concept that allowed GDI to load different device drivers is that which allowed the Windows beat to load different Windows programs, and for these programs to invoke API calls from the shared USER and GDI libraries. That concept was "dynamic linking".

In a conventional non-shared static library, sections of code are simply added to the calling program when its executable is congenital at the "linking" stage; if two programs call the same routine, the routine is included in both the programs during the linking stage of the two. With dynamic linking, shared code is placed into a single, separate file. The programs that telephone call this file are connected to it at run time, with the operating system (or, in the instance of early versions of Windows, the Bone-extension), performing the binding.

For those early versions of Windows (1.0 to iii.11), the DLLs were the foundation for the entire GUI. As such, display drivers were merely DLLs with a .DRV extension that provided custom implementations of the same cartoon API through a unified device driver interface (DDI), and the Drawing (GDI) and GUI (USER) APIs were only the function calls exported by the GDI and USER, system DLLs with .EXE extension.

This notion of edifice up the operating organisation from a drove of dynamically loaded libraries is a core concept of Windows that persists as of 2015[update]. DLLs provide the standard benefits of shared libraries, such equally modularity. Modularity allows changes to exist made to code and information in a single cocky-contained DLL shared by several applications without any change to the applications themselves.

Some other benefit of modularity is the use of generic interfaces for plug-ins. A single interface may be adult which allows old likewise as new modules to exist integrated seamlessly at run-fourth dimension into pre-existing applications, without any modification to the application itself. This concept of dynamic extensibility is taken to the extreme with the Component Object Model, the underpinnings of ActiveX.

In Windows 1.x, 2.ten and three.x, all Windows applications shared the aforementioned address space every bit well every bit the aforementioned retention. A DLL was only loaded once into this address space; from then on, all programs using the library accessed it. The library's data was shared across all the programs. This could exist used as an indirect class of inter-process communication, or information technology could accidentally decadent the different programs. With the introduction of 32-bit libraries in Windows 95, every process ran in its own accost space. While the DLL code may be shared, the data is private except where shared information is explicitly requested past the library. That said, large swathes of Windows 95, Windows 98 and Windows Me were built from 16-bit libraries, which limited the performance of the Pentium Pro microprocessor when launched, and ultimately limited the stability and scalability of the DOS-based versions of Windows.

Although DLLs are the core of the Windows architecture, they have several drawbacks, collectively called "DLL hell".[2] Equally of 2015[update] Microsoft promotes .Net Framework every bit one solution to the problems of DLL hell, although they now promote virtualization-based solutions such as Microsoft Virtual PC and Microsoft Awarding Virtualization, because they offer superior isolation betwixt applications. An culling mitigating solution to DLL hell has been to implement side-by-side assembly.

Features [edit]

Since DLLs are substantially the same as EXEs, the choice of which to produce every bit part of the linking procedure is for clarity, since it is possible to export functions and data from either.

It is not possible to straight execute a DLL, since it requires an EXE for the operating system to load it through an entry indicate, hence the existence of utilities like RUNDLL.EXE or RUNDLL32.EXE which provide the entry point and minimal framework for DLLs that contain enough functionality to execute without much support.

DLLs provide a mechanism for shared lawmaking and data, allowing a programmer of shared code/information to upgrade functionality without requiring applications to be re-linked or re-compiled. From the application development point of view, Windows and Os/2 can be thought of equally a collection of DLLs that are upgraded, allowing applications for one version of the OS to piece of work in a later one, provided that the Bone vendor has ensured that the interfaces and functionality are uniform.

DLLs execute in the memory infinite of the calling process and with the same access permissions, which means there is little overhead in their use, but also that there is no protection for the calling program if the DLL has any sort of bug.

Memory management [edit]

In Windows API, DLL files are organized into sections. Each section has its ain fix of attributes, such as being writable or read-just, executable (for lawmaking) or not-executable (for data), and then on.

The code in a DLL is usually shared among all the processes that use the DLL; that is, they occupy a unmarried place in concrete memory, and do not take up space in the folio file. Windows does non utilize position-independent code for its DLLs; instead, the code undergoes relocation as it is loaded, fixing addresses for all its entry points at locations which are free in the retention infinite of the start process to load the DLL. In older versions of Windows, in which all running processes occupied a single common address space, a single copy of the DLL's code would always exist sufficient for all the processes. However, in newer versions of Windows which use split address spaces for each plan, it is simply possible to use the same relocated copy of the DLL in multiple programs if each program has the same virtual addresses free to accommodate the DLL's code. If some programs (or their combination of already-loaded DLLs) do not have those addresses costless, then an additional physical copy of the DLL's lawmaking will demand to exist created, using a different set of relocated entry points. If the physical memory occupied by a code section is to be reclaimed, its contents are discarded, and after reloaded directly from the DLL file as necessary.

In dissimilarity to code sections, the data sections of a DLL are usually individual; that is, each process using the DLL has its own copy of all the DLL'southward data. Optionally, data sections can be fabricated shared, allowing inter-process communication via this shared memory area. However, because user restrictions do not utilise to the use of shared DLL memory, this creates a security hole; namely, one procedure can corrupt the shared data, which volition likely cause all other sharing processes to behave undesirably. For example, a procedure running under a guest account can in this way decadent another process running under a privileged account. This is an important reason to avert the use of shared sections in DLLs.

If a DLL is compressed by certain executable packers (e.grand. UPX), all of its code sections are marked as read and write, and will exist unshared. Read-and-write lawmaking sections, much similar individual data sections, are private to each process. Thus DLLs with shared data sections should not be compressed if they are intended to exist used simultaneously by multiple programs, since each programme example would have to carry its own copy of the DLL, resulting in increased retentivity consumption.

Import libraries [edit]

Similar static libraries, import libraries for DLLs are noted by the .lib file extension. For instance, kernel32.dll, the primary dynamic library for Windows's base of operations functions such every bit file creation and retention direction, is linked via kernel32.lib. The usual mode to tell an import library from a proper static library is by size: the import library is much smaller every bit information technology but contains symbols referring to the bodily DLL, to be candy at link-fourth dimension. Both nevertheless are Unix ar format files.

Linking to dynamic libraries is commonly handled by linking to an import library when building or linking to create an executable file. The created executable then contains an import address table (IAT) by which all DLL part calls are referenced (each referenced DLL function contains its own entry in the IAT). At run-fourth dimension, the IAT is filled with appropriate addresses that point directly to a role in the separately loaded DLL.[3]

In Cygwin/MSYS and MinGW, import libraries are conventionally given the suffix .dll.a, combining both the Windows DLL suffix and the Unix ar suffix. The file format is similar, but the symbols used to mark the imports are different (_head_foo_dll vs __IMPORT_DESCRIPTOR_foo).[4] Although its GNU Binutils toolchain tin can generate import libraries and link to them, information technology is faster to link to the DLL directly.[5] An experimental tool in MinGW called genlib can exist used to generate import libs with MSVC-mode symbols.

Symbol resolution and bounden [edit]

Each role exported by a DLL is identified by a numeric ordinal and optionally a proper name. Besides, functions can exist imported from a DLL either past ordinal or past name. The ordinal represents the position of the office's address pointer in the DLL Export Address table. It is mutual for internal functions to be exported by ordinal merely. For most Windows API functions only the names are preserved beyond dissimilar Windows releases; the ordinals are subject to change. Thus, i cannot reliably import Windows API functions by their ordinals.

Importing functions by ordinal provides only slightly better performance than importing them by proper noun: consign tables of DLLs are ordered by name, then a binary search tin can be used to find a office. The index of the found name is then used to wait upward the ordinal in the Export Ordinal table. In 16-chip Windows, the name table was non sorted, so the name lookup overhead was much more noticeable.

It is also possible to bind an executable to a specific version of a DLL, that is, to resolve the addresses of imported functions at compile-time. For bound imports, the linker saves the timestamp and checksum of the DLL to which the import is spring. At run-time, Windows checks to come across if the aforementioned version of library is being used, and if and so, Windows bypasses processing the imports. Otherwise, if the library is different from the i which was leap to, Windows processes the imports in a normal way.

Spring executables load somewhat faster if they are run in the same environment that they were compiled for, and exactly the same time if they are run in a different environment, and so there is no drawback for binding the imports. For case, all the standard Windows applications are spring to the system DLLs of their respective Windows release. A good opportunity to bind an application'south imports to its target surroundings is during the application's installation. This keeps the libraries "bound" until the adjacent Bone update. Information technology does, however, change the checksum of the executable, then it is not something that can be washed with signed programs, or programs that are managed by a configuration management tool that uses checksums (such as MD5 checksums) to manage file versions. As more than recent Windows versions have moved away from having stock-still addresses for every loaded library (for security reasons), the opportunity and value of binding an executable is decreasing.

Explicit run-time linking [edit]

DLL files may be explicitly loaded at run-time, a process referred to simply as run-fourth dimension dynamic linking past Microsoft, by using the LoadLibrary (or LoadLibraryEx) API function. The GetProcAddress API function is used to look upwards exported symbols by name, and FreeLibrary – to unload the DLL. These functions are coordinating to dlopen, dlsym, and dlclose in the POSIX standard API.

The procedure for explicit run-time linking is the same in any language that supports pointers to functions, since information technology depends on the Windows API rather than language constructs.

Delayed loading [edit]

Normally, an application that is linked against a DLL's import library will fail to start if the DLL cannot be found, considering Windows volition non run the application unless it can find all of the DLLs that the application may need. Even so an application may be linked against an import library to allow delayed loading of the dynamic library.[6] In this instance, the operating system volition non try to discover or load the DLL when the application starts; instead, a stub is included in the awarding by the linker which will try to discover and load the DLL through LoadLibrary and GetProcAddress when one of its functions is chosen. If the DLL cannot be found or loaded, or the chosen function does not exist, the application will generate an exception, which may be caught and handled appropriately. If the awarding does not handle the exception, information technology will be caught by the operating organization, which will terminate the program with an error message.

The delayed loading mechanism likewise provides notification hooks, assuasive the awarding to perform additional processing or mistake handling when the DLL is loaded and/or any DLL part is called.

Compiler and linguistic communication considerations [edit]

Delphi [edit]

In a source file, the keyword library is used instead of program. At the cease of the file, the functions to exist exported are listed in exports clause.

Delphi does not need LIB files to import functions from DLLs; to link to a DLL, the external keyword is used in the function declaration to signal the DLL proper name, followed by proper noun to proper noun the symbol (if different) or index to identify the index.

Microsoft Visual Basic [edit]

In Visual Bones (VB), only run-fourth dimension linking is supported; but in addition to using LoadLibrary and GetProcAddress API functions, declarations of imported functions are allowed.

When importing DLL functions through declarations, VB will generate a run-time fault if the DLL file cannot be constitute. The developer can catch the error and handle it accordingly.

When creating DLLs in VB, the IDE volition only allow creation of ActiveX DLLs, however methods take been created[7] to let the user to explicitly tell the linker to include a .DEF file which defines the ordinal position and name of each exported role. This allows the user to create a standard Windows DLL using Visual Basic (Version half dozen or lower) which can be referenced through a "Declare" argument.

C and C++ [edit]

Microsoft Visual C++ (MSVC) provides several extensions to standard C++ which allow functions to be specified every bit imported or exported directly in the C++ code; these accept been adopted past other Windows C and C++ compilers, including Windows versions of GCC. These extensions use the attribute __declspec earlier a office declaration. Annotation that when C functions are accessed from C++, they must also be declared as extern "C" in C++ lawmaking, to inform the compiler that the C linkage should be used.[eight]

Besides specifying imported or exported functions using __declspec attributes, they may exist listed in IMPORT or EXPORTS section of the DEF file used past the project. The DEF file is processed by the linker, rather than the compiler, and thus it is non specific to C++.

DLL compilation will produce both DLL and LIB files. The LIB file (import library) is used to link against a DLL at compile-time; it is not necessary for run-fourth dimension linking. Unless the DLL is a Component Object Model (COM) server, the DLL file must be placed in one of the directories listed in the PATH environment variable, in the default system directory, or in the aforementioned directory equally the program using information technology. COM server DLLs are registered using regsvr32.exe, which places the DLL's location and its globally unique ID (GUID) in the registry. Programs can then use the DLL by looking up its GUID in the registry to find its location or create an instance of the COM object indirectly using its class identifier and interface identifier.

Programming examples [edit]

Using DLL imports [edit]

The following examples show how to utilize linguistic communication-specific bindings to import symbols for linking against a DLL at compile-time.

Delphi

                        {$APPTYPE Console}            plan            Example            ;            // import part that adds ii numbers            function            AddNumbers            (            a            ,            b            :            Double            )            :            Double            ;            StdCall            ;            external            'Example.dll'            ;            // main program            var            R            :            Double            ;            begin            R            :=            AddNumbers            (            1            ,            two            )            ;            Writeln            (            'The result was: '            ,            R            )            ;            end            .          

C

Example.lib file must be included (assuming that Example.dll is generated) in the project (Add Existing Item option for Project!) before static linking. The file Case.lib is automatically generated by the compiler when compiling the DLL. Not executing the above statement would cause linking error equally the linker would non know where to find the definition of AddNumbers. The DLL Case.dll may as well have to be copied to the location where the .exe file would be generated by the following code.

                        #include                                    <windows.h>                        #include                                    <stdio.h>                        // Import function that adds two numbers            extern                                    "C"                                    __declspec            (            dllimport            )                                    double                                    AddNumbers            (            double                                    a            ,                                    double                                    b            );                        int                                    main            (            int                                    argc            ,                                    char                                    *            argv            [])                        {                                                double                                    result                                    =                                    AddNumbers            (            1            ,                                    2            );                                                printf            (            "The outcome was: %f            \n            "            ,                                    result            );                                                return                                    0            ;                        }                      

Using explicit run-time linking [edit]

The following examples show how to use the run-fourth dimension loading and linking facilities using language-specific Windows API bindings.

Notation that all of the four samples are vulnerable to DLL preloading attacks, since example.dll tin can be resolved to a identify unintended past the author (the current working directory goes earlier system library locations), and thus to a malicious version of the library. Run into the reference for Microsoft's guidance on condom library loading: i should use SetDllDirectoryW in kernel32 to remove the electric current-directory lookup before any libraries are loaded.[9]

Microsoft Visual Bones [edit]

                        Option            Explicit            Declare            Part            AddNumbers            Lib            "Example.dll"            _            (            ByVal            a            As            Double            ,            ByVal            b            As            Double            )            Equally            Double            Sub            Main            ()            Dim            Result            Equally            Double            Result            =            AddNumbers            (            1            ,            2            )            Debug            .            Print            "The effect was: "            &            Result            End            Sub          

Delphi [edit]

                        program            Example            ;            {$APPTYPE CONSOLE}            uses            Windows            ;            var            AddNumbers            :            role            (            a            ,            b            :            integer            )            :            Double            ;            StdCall            ;            LibHandle            :            HMODULE            ;            brainstorm            LibHandle            :=            LoadLibrary            (            'example.dll'            )            ;            if            LibHandle            <>            0            then            AddNumbers            :=            GetProcAddress            (            LibHandle            ,            'AddNumbers'            )            ;            if            Assigned            (            AddNumbers            )            and so            Writeln            (            'ane + 2 = '            ,            AddNumbers            (            ane            ,            two            )            )            ;            Readln            ;            stop            .          

C [edit]

                        #include                                    <windows.h>                        #include                                    <stdio.h>                        // DLL role signature            typedef                                    double                                    (            *            importFunction            )(            double            ,                                    double            );                        int                                    principal            (            int                                    argc            ,                                    char                                    **            argv            )                        {                                                importFunction                                    addNumbers            ;                                                double                                    consequence            ;                                                HINSTANCE                                    hinstLib            ;                                                // Load DLL file                                    hinstLib                                    =                                    LoadLibrary            (            TEXT            (            "Case.dll"            ));                                                if                                    (            hinstLib                                    ==                                    NULL            )                                    {                                                printf            (            "ERROR: unable to load DLL            \n            "            );                                                render                                    one            ;                                                }                                                // Get function pointer                                    addNumbers                                    =                                    (            importFunction            )                                    GetProcAddress            (            hinstLib            ,                                    "AddNumbers"            );                                                if                                    (            addNumbers                                    ==                                    Nada            )                                    {                                                printf            (            "Error: unable to find DLL office            \n            "            );                                                FreeLibrary            (            hinstLib            );                                                return                                    i            ;                                                }                                                // Phone call role.                                    effect                                    =                                    addNumbers            (            1            ,                                    3            );                                                // Unload DLL file                                    FreeLibrary            (            hinstLib            );                                                // Display result                                    printf            (            "The upshot was: %f            \n            "            ,                                    result            );                                                return                                    0            ;                        }                      

Python [edit]

The Python ctypes bounden will utilise POSIX API on POSIX systems.

                        import            ctypes            my_dll            =            ctypes            .            cdll            .            LoadLibrary            (            "Example.dll"            )            # The post-obit "restype" method specification is needed to brand            # Python understand what type is returned by the part.            my_dll            .            AddNumbers            .            restype            =            ctypes            .            c_double            p            =            my_dll            .            AddNumbers            (            ctypes            .            c_double            (            one.0            ),            ctypes            .            c_double            (            2.0            ))            print            (            "The event was:"            ,            p            )          

Component Object Model [edit]

The Component Object Model (COM) defines a binary standard to host the implementation of objects in DLL and EXE files. It provides mechanisms to locate and version those files equally well as a language-independent and machine-readable description of the interface. Hosting COM objects in a DLL is more than lightweight and allows them to share resources with the client procedure. This allows COM objects to implement powerful back-ends to unproblematic GUI forepart ends such as Visual Basic and ASP. They can also exist programmed from scripting languages.[ten]

DLL hijacking [edit]

Due to a vulnerability unremarkably known equally DLL hijacking, DLL spoofing, DLL preloading or binary planting, many programs will load and execute a malicious DLL contained in the same folder as a data file opened by these programs.[xi] [12] [xiii] [14] The vulnerability was discovered by Georgi Guninski in 2000.[15] In Baronial 2010 information technology gained worldwide publicity afterward ACROS Security rediscovered information technology once again and many hundreds of programs were plant vulnerable.[16] Programs that are run from dangerous locations, i.e. user-writable folders like the Downloads or the Temp directory, are almost e'er susceptible to this vulnerability.[17] [18] [19] [20] [21] [22] [23]

See also [edit]

  • Dependency Walker, a utility which displays exported and imported functions of DLL and EXE files
  • Dynamic library
  • Library (calculating)
  • Linker (computing)
  • Loader (computing)
  • Moricons.dll
  • Object file
  • Shared library
  • Static library
  • DLL Hell

References [edit]

  • Hart, Johnson. Windows System Programming Third Edition. Addison-Wesley, 2005. ISBN 0-321-25619-0.
  • Rector, Brent et al. Win32 Programming. Addison-Wesley Developers Press, 1997. ISBN 0-201-63492-9.

External links [edit]

  • dllexport, dllimport on MSDN
  • Dynamic-Link Libraries on MSDN
  • Dynamic-Link Library Security on MSDN
  • Dynamic-Link Library Search Lodge on MSDN
  • Microsoft Security Advisory: Insecure library loading could allow remote code execution
  • What is a DLL? on Microsoft support site
  • Dynamic-Link Library Functions on MSDN
  • Microsoft Portable Executable and Common Object File Format Specification
  • Microsoft specification for dll files
  • Carpet Bombing and Directory Poisoning
  • MS09-014: Addressing the Safari Rug Flop vulnerability
  • More data about the DLL Preloading remote attack vector
  • An update on the DLL-preloading remote attack vector
  • Load Library Safely
  1. ^ Microsoft Corporation. "Creating a Resources-Only DLL". Microsoft Developer Network Library.
  2. ^ "The Cease of DLL Hell". Microsoft Corporation. Archived from the original on 2008-05-06. Retrieved 2009-07-11 .
  3. ^ "Understanding the Import Address Tabular array".
  4. ^ "Edifice and Using DLLs". The import library is a regular UNIX-like .a library, but it only contains the tiny fleck of information needed to tell the OS how the program interacts with ("imports") the dll. This information is linked into .exe.
  5. ^ "ld and WIN32". ld documentation.
  6. ^ "Linker Support for Filibuster-Loaded DLLs". Microsoft Corporation. Retrieved 2009-07-11 .
  7. ^ Petrusha, Ron (2005-04-26). "Creating a Windows DLL with Visual Bones". O'Reilly Media. Retrieved 2009-07-11 .
  8. ^ MSDN, Using extern to Specify Linkage
  9. ^ "Secure loading of libraries to forestall DLL preloading attacks". Microsoft Support . Retrieved 28 October 2019.
  10. ^ Satran, Michael. "Component Object Model (COM)". msdn.microsoft.com.
  11. ^ DLL Spoofing in Windows
  12. ^ "DLL Preloading Attacks". msdn.com . Retrieved 25 March 2018.
  13. ^ "More data about the DLL Preloading remote attack vector". technet.com . Retrieved 25 March 2018.
  14. ^ "An update on the DLL-preloading remote assault vector". technet.com . Retrieved 25 March 2018.
  15. ^ "Double clicking on MS Office documents from Windows Explorer may execute arbitrary programs in some cases". www.guninski.com . Retrieved 25 March 2018.
  16. ^ "Binary Planting - The Official Web Site of a Forgotten Vulnerability . ACROS Security". world wide web.binaryplanting.com . Retrieved 25 March 2018.
  17. ^ Carpet Bombing and Directory Poisoning
  18. ^ "Dev to Mozilla: Please dump ancient Windows install processes". theregister.co.uk . Retrieved 25 March 2018.
  19. ^ "Gpg4win - Security Advisory Gpg4win 2015-11-25". world wide web.gpg4win.org . Retrieved 25 March 2018.
  20. ^ "McAfee KB - McAfee Security Message: Security patch for several McAfee installers and uninstallers (CVE-2015-8991, CVE-2015-8992, and CVE-2015-8993) (TS102462)". service.mcafee.com . Retrieved 25 March 2018.
  21. ^ "fsc-2015-4 - F-Secure Labs". www.f-secure.com. Archived from the original on 31 July 2017. Retrieved 25 March 2018.
  22. ^ "ScanNow DLL Search Order Hijacking Vulnerability and Deprecation". rapid7.com. 21 December 2015. Retrieved 25 March 2018.
  23. ^ Team, VeraCrypt. "oss-sec: CVE-2016-1281: TrueCrypt and VeraCrypt Windows installers allow arbitrary code execution with elevation of privilege". seclists.org . Retrieved 25 March 2018.

burgeswastand98.blogspot.com

Source: https://en.wikipedia.org/wiki/Dynamic-link_library

0 Response to "what program is supposed to be associated with dll"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel