Is there any way to get my own image base without calling any WinAPI functions, such as GetModuleHandle?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
3
down vote

favorite
1












Is there any way to get the image base of an .exe without calling WinAPI functions (i.e. imported functions, so that it can't be easily viewed in a diassembler/debugger)?



I've been thinking of declaring a global variable anywhere in code and reading its address in a loop backwards until e.g.MZ is found (obviously checking for NULL in the meantime). However, there may be a section which isn't readable, a string in .rdata which contains the MZ characters or some value (especially a function address or generally pointers) that contains the MZ bytes (0x4D, 0x5A) (and probably a few more "situations").



Have you any idea how to achieve that? Is it even possible?










share|improve this question







New contributor




Jason is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.























    up vote
    3
    down vote

    favorite
    1












    Is there any way to get the image base of an .exe without calling WinAPI functions (i.e. imported functions, so that it can't be easily viewed in a diassembler/debugger)?



    I've been thinking of declaring a global variable anywhere in code and reading its address in a loop backwards until e.g.MZ is found (obviously checking for NULL in the meantime). However, there may be a section which isn't readable, a string in .rdata which contains the MZ characters or some value (especially a function address or generally pointers) that contains the MZ bytes (0x4D, 0x5A) (and probably a few more "situations").



    Have you any idea how to achieve that? Is it even possible?










    share|improve this question







    New contributor




    Jason is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.





















      up vote
      3
      down vote

      favorite
      1









      up vote
      3
      down vote

      favorite
      1






      1





      Is there any way to get the image base of an .exe without calling WinAPI functions (i.e. imported functions, so that it can't be easily viewed in a diassembler/debugger)?



      I've been thinking of declaring a global variable anywhere in code and reading its address in a loop backwards until e.g.MZ is found (obviously checking for NULL in the meantime). However, there may be a section which isn't readable, a string in .rdata which contains the MZ characters or some value (especially a function address or generally pointers) that contains the MZ bytes (0x4D, 0x5A) (and probably a few more "situations").



      Have you any idea how to achieve that? Is it even possible?










      share|improve this question







      New contributor




      Jason is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      Is there any way to get the image base of an .exe without calling WinAPI functions (i.e. imported functions, so that it can't be easily viewed in a diassembler/debugger)?



      I've been thinking of declaring a global variable anywhere in code and reading its address in a loop backwards until e.g.MZ is found (obviously checking for NULL in the meantime). However, there may be a section which isn't readable, a string in .rdata which contains the MZ characters or some value (especially a function address or generally pointers) that contains the MZ bytes (0x4D, 0x5A) (and probably a few more "situations").



      Have you any idea how to achieve that? Is it even possible?







      windows pe executable exe






      share|improve this question







      New contributor




      Jason is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      Jason is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      Jason is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 2 hours ago









      Jason

      183




      183




      New contributor




      Jason is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Jason is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Jason is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          I can think of a couple of ways of doing that



          Scanning memory from EIP



          You could easily get the EIP of your own code without calling any APIs. There are a few ways to achieve that using inline assembly, but the most common one is to include the following two instructions:



          call $+5
          pop eax


          This works because call will push the next address (where pop eax is onto the stack) and then execute the instruction right after it (again, our pop eax). When pop eax is executed, it'll pop the address just pushed by call $+5 into a register.



          After you got your EIP value you can easily scan backwards as you thought of doing, but this time starting at a position a lot closer to your image base.



          Keeping in mind image bases are aligned to page boundaries, you can scan in PAGE_SIZE (4096 bytes) intervals.



          Reading loaded modules from PEB



          The Process Environment Block structure is accessible using a designated segment register (fs on 32bit systems and gs on 64 bit systems) which stores the address of the Thread Information Block from which the PEB is reachable. Although most of the PEB is undocumented, in it is a lot of data relating to the operational aspects of the currently running process.



          One such piece of information is the ImageBaseAddress, an undocumented (but consistent) field that holds the process's image base. If you're interested in the .exe's image base (opposed to a loaded DLLs image base), this will do.



          If you want something more reliable you could use the Ldr member, which points to a PEB_LDR_DATA structure which points to a linked list of LDR_DATA_TABLE_ENTRYs, which lists all loaded modules, their addresses and a lot of other information about each loaded module. Your executable's image base is the DllBase field.






          share|improve this answer


















          • 2




            PEB.ImageBaseAddress will be easier than walking the Ldr structures.
            – josh poley
            2 hours ago










          • @Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read the eip in 0x1000 intervals. If you meant something like: while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;, then what if the image base actually was 0x400000 and the eip was, say, 0x400ABC? Am I missing something?
            – Jason
            1 hour ago











          • @joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
            – NirIzr
            1 hour ago










          • @Jason You can easily align the address to a 4k boundary by performing eip & ~(4096-1)
            – NirIzr
            1 hour ago











          • @Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
            – Jason
            1 hour ago

















          up vote
          1
          down vote













          If you use Visual C++, you can use the special symbol __ImageBase which points to image base of the current module. For example, here's code from VS2010 CRT source (pesect.c):



          BOOL __cdecl _IsNonwritableInCurrentImage(
          PBYTE pTarget
          )

          PBYTE pImageBase;
          DWORD_PTR rvaTarget;
          PIMAGE_SECTION_HEADER pSection;

          pImageBase = (PBYTE)&__ImageBase;

          __try
          //
          // Make sure __ImageBase does address a PE image. This is likely an
          // unnecessary check, since we should be running from a normal image,
          // but it is fast, this routine is rarely called, and the normal call
          // is for security purposes. If we don't have a PE image, return
          // failure.
          //
          if (!_ValidateImageBase(pImageBase))

          return FALSE;


          //
          // Convert the targetaddress to a Relative Virtual Address (RVA) within
          // the image, and find the corresponding PE section. Return failure if
          // the target address is not found within the current image.
          //
          rvaTarget = pTarget - pImageBase;
          pSection = _FindPESection(pImageBase, rvaTarget);
          if (pSection == NULL)

          return FALSE;


          //
          // Check the section characteristics to see if the target address is
          // located within a writable section, returning a failure if yes.
          //
          return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;

          __except (GetExceptionCode() == STATUS_ACCESS_VIOLATION)

          //
          // Just return failure if the PE image is corrupted in any way that
          // triggers an AV.
          //
          return FALSE;




          At the top of the file there is code declaring this variable as extern:



          #if defined (_WIN64) && defined (_M_IA64)
          #pragma section(".base", long, read)
          __declspec(allocate(".base"))
          extern IMAGE_DOS_HEADER __ImageBase;
          #else /* defined (_WIN64) && defined (_M_IA64) */
          extern IMAGE_DOS_HEADER __ImageBase;
          #endif /* defined (_WIN64) && defined (_M_IA64) */


          So it may be that the key is the .base section and not the variable name by itself.






          share|improve this answer




















            Your Answer







            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "489"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            noCode: true, onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );






            Jason is a new contributor. Be nice, and check out our Code of Conduct.









             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2freverseengineering.stackexchange.com%2fquestions%2f19660%2fis-there-any-way-to-get-my-own-image-base-without-calling-any-winapi-functions%23new-answer', 'question_page');

            );

            Post as a guest






























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            3
            down vote



            accepted










            I can think of a couple of ways of doing that



            Scanning memory from EIP



            You could easily get the EIP of your own code without calling any APIs. There are a few ways to achieve that using inline assembly, but the most common one is to include the following two instructions:



            call $+5
            pop eax


            This works because call will push the next address (where pop eax is onto the stack) and then execute the instruction right after it (again, our pop eax). When pop eax is executed, it'll pop the address just pushed by call $+5 into a register.



            After you got your EIP value you can easily scan backwards as you thought of doing, but this time starting at a position a lot closer to your image base.



            Keeping in mind image bases are aligned to page boundaries, you can scan in PAGE_SIZE (4096 bytes) intervals.



            Reading loaded modules from PEB



            The Process Environment Block structure is accessible using a designated segment register (fs on 32bit systems and gs on 64 bit systems) which stores the address of the Thread Information Block from which the PEB is reachable. Although most of the PEB is undocumented, in it is a lot of data relating to the operational aspects of the currently running process.



            One such piece of information is the ImageBaseAddress, an undocumented (but consistent) field that holds the process's image base. If you're interested in the .exe's image base (opposed to a loaded DLLs image base), this will do.



            If you want something more reliable you could use the Ldr member, which points to a PEB_LDR_DATA structure which points to a linked list of LDR_DATA_TABLE_ENTRYs, which lists all loaded modules, their addresses and a lot of other information about each loaded module. Your executable's image base is the DllBase field.






            share|improve this answer


















            • 2




              PEB.ImageBaseAddress will be easier than walking the Ldr structures.
              – josh poley
              2 hours ago










            • @Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read the eip in 0x1000 intervals. If you meant something like: while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;, then what if the image base actually was 0x400000 and the eip was, say, 0x400ABC? Am I missing something?
              – Jason
              1 hour ago











            • @joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
              – NirIzr
              1 hour ago










            • @Jason You can easily align the address to a 4k boundary by performing eip & ~(4096-1)
              – NirIzr
              1 hour ago











            • @Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
              – Jason
              1 hour ago














            up vote
            3
            down vote



            accepted










            I can think of a couple of ways of doing that



            Scanning memory from EIP



            You could easily get the EIP of your own code without calling any APIs. There are a few ways to achieve that using inline assembly, but the most common one is to include the following two instructions:



            call $+5
            pop eax


            This works because call will push the next address (where pop eax is onto the stack) and then execute the instruction right after it (again, our pop eax). When pop eax is executed, it'll pop the address just pushed by call $+5 into a register.



            After you got your EIP value you can easily scan backwards as you thought of doing, but this time starting at a position a lot closer to your image base.



            Keeping in mind image bases are aligned to page boundaries, you can scan in PAGE_SIZE (4096 bytes) intervals.



            Reading loaded modules from PEB



            The Process Environment Block structure is accessible using a designated segment register (fs on 32bit systems and gs on 64 bit systems) which stores the address of the Thread Information Block from which the PEB is reachable. Although most of the PEB is undocumented, in it is a lot of data relating to the operational aspects of the currently running process.



            One such piece of information is the ImageBaseAddress, an undocumented (but consistent) field that holds the process's image base. If you're interested in the .exe's image base (opposed to a loaded DLLs image base), this will do.



            If you want something more reliable you could use the Ldr member, which points to a PEB_LDR_DATA structure which points to a linked list of LDR_DATA_TABLE_ENTRYs, which lists all loaded modules, their addresses and a lot of other information about each loaded module. Your executable's image base is the DllBase field.






            share|improve this answer


















            • 2




              PEB.ImageBaseAddress will be easier than walking the Ldr structures.
              – josh poley
              2 hours ago










            • @Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read the eip in 0x1000 intervals. If you meant something like: while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;, then what if the image base actually was 0x400000 and the eip was, say, 0x400ABC? Am I missing something?
              – Jason
              1 hour ago











            • @joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
              – NirIzr
              1 hour ago










            • @Jason You can easily align the address to a 4k boundary by performing eip & ~(4096-1)
              – NirIzr
              1 hour ago











            • @Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
              – Jason
              1 hour ago












            up vote
            3
            down vote



            accepted







            up vote
            3
            down vote



            accepted






            I can think of a couple of ways of doing that



            Scanning memory from EIP



            You could easily get the EIP of your own code without calling any APIs. There are a few ways to achieve that using inline assembly, but the most common one is to include the following two instructions:



            call $+5
            pop eax


            This works because call will push the next address (where pop eax is onto the stack) and then execute the instruction right after it (again, our pop eax). When pop eax is executed, it'll pop the address just pushed by call $+5 into a register.



            After you got your EIP value you can easily scan backwards as you thought of doing, but this time starting at a position a lot closer to your image base.



            Keeping in mind image bases are aligned to page boundaries, you can scan in PAGE_SIZE (4096 bytes) intervals.



            Reading loaded modules from PEB



            The Process Environment Block structure is accessible using a designated segment register (fs on 32bit systems and gs on 64 bit systems) which stores the address of the Thread Information Block from which the PEB is reachable. Although most of the PEB is undocumented, in it is a lot of data relating to the operational aspects of the currently running process.



            One such piece of information is the ImageBaseAddress, an undocumented (but consistent) field that holds the process's image base. If you're interested in the .exe's image base (opposed to a loaded DLLs image base), this will do.



            If you want something more reliable you could use the Ldr member, which points to a PEB_LDR_DATA structure which points to a linked list of LDR_DATA_TABLE_ENTRYs, which lists all loaded modules, their addresses and a lot of other information about each loaded module. Your executable's image base is the DllBase field.






            share|improve this answer














            I can think of a couple of ways of doing that



            Scanning memory from EIP



            You could easily get the EIP of your own code without calling any APIs. There are a few ways to achieve that using inline assembly, but the most common one is to include the following two instructions:



            call $+5
            pop eax


            This works because call will push the next address (where pop eax is onto the stack) and then execute the instruction right after it (again, our pop eax). When pop eax is executed, it'll pop the address just pushed by call $+5 into a register.



            After you got your EIP value you can easily scan backwards as you thought of doing, but this time starting at a position a lot closer to your image base.



            Keeping in mind image bases are aligned to page boundaries, you can scan in PAGE_SIZE (4096 bytes) intervals.



            Reading loaded modules from PEB



            The Process Environment Block structure is accessible using a designated segment register (fs on 32bit systems and gs on 64 bit systems) which stores the address of the Thread Information Block from which the PEB is reachable. Although most of the PEB is undocumented, in it is a lot of data relating to the operational aspects of the currently running process.



            One such piece of information is the ImageBaseAddress, an undocumented (but consistent) field that holds the process's image base. If you're interested in the .exe's image base (opposed to a loaded DLLs image base), this will do.



            If you want something more reliable you could use the Ldr member, which points to a PEB_LDR_DATA structure which points to a linked list of LDR_DATA_TABLE_ENTRYs, which lists all loaded modules, their addresses and a lot of other information about each loaded module. Your executable's image base is the DllBase field.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 1 hour ago

























            answered 2 hours ago









            NirIzr

            8,77712268




            8,77712268







            • 2




              PEB.ImageBaseAddress will be easier than walking the Ldr structures.
              – josh poley
              2 hours ago










            • @Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read the eip in 0x1000 intervals. If you meant something like: while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;, then what if the image base actually was 0x400000 and the eip was, say, 0x400ABC? Am I missing something?
              – Jason
              1 hour ago











            • @joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
              – NirIzr
              1 hour ago










            • @Jason You can easily align the address to a 4k boundary by performing eip & ~(4096-1)
              – NirIzr
              1 hour ago











            • @Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
              – Jason
              1 hour ago












            • 2




              PEB.ImageBaseAddress will be easier than walking the Ldr structures.
              – josh poley
              2 hours ago










            • @Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read the eip in 0x1000 intervals. If you meant something like: while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;, then what if the image base actually was 0x400000 and the eip was, say, 0x400ABC? Am I missing something?
              – Jason
              1 hour ago











            • @joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
              – NirIzr
              1 hour ago










            • @Jason You can easily align the address to a 4k boundary by performing eip & ~(4096-1)
              – NirIzr
              1 hour ago











            • @Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
              – Jason
              1 hour ago







            2




            2




            PEB.ImageBaseAddress will be easier than walking the Ldr structures.
            – josh poley
            2 hours ago




            PEB.ImageBaseAddress will be easier than walking the Ldr structures.
            – josh poley
            2 hours ago












            @Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read the eip in 0x1000 intervals. If you meant something like: while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;, then what if the image base actually was 0x400000 and the eip was, say, 0x400ABC? Am I missing something?
            – Jason
            1 hour ago





            @Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read the eip in 0x1000 intervals. If you meant something like: while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;, then what if the image base actually was 0x400000 and the eip was, say, 0x400ABC? Am I missing something?
            – Jason
            1 hour ago













            @joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
            – NirIzr
            1 hour ago




            @joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
            – NirIzr
            1 hour ago












            @Jason You can easily align the address to a 4k boundary by performing eip & ~(4096-1)
            – NirIzr
            1 hour ago





            @Jason You can easily align the address to a 4k boundary by performing eip & ~(4096-1)
            – NirIzr
            1 hour ago













            @Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
            – Jason
            1 hour ago




            @Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
            – Jason
            1 hour ago










            up vote
            1
            down vote













            If you use Visual C++, you can use the special symbol __ImageBase which points to image base of the current module. For example, here's code from VS2010 CRT source (pesect.c):



            BOOL __cdecl _IsNonwritableInCurrentImage(
            PBYTE pTarget
            )

            PBYTE pImageBase;
            DWORD_PTR rvaTarget;
            PIMAGE_SECTION_HEADER pSection;

            pImageBase = (PBYTE)&__ImageBase;

            __try
            //
            // Make sure __ImageBase does address a PE image. This is likely an
            // unnecessary check, since we should be running from a normal image,
            // but it is fast, this routine is rarely called, and the normal call
            // is for security purposes. If we don't have a PE image, return
            // failure.
            //
            if (!_ValidateImageBase(pImageBase))

            return FALSE;


            //
            // Convert the targetaddress to a Relative Virtual Address (RVA) within
            // the image, and find the corresponding PE section. Return failure if
            // the target address is not found within the current image.
            //
            rvaTarget = pTarget - pImageBase;
            pSection = _FindPESection(pImageBase, rvaTarget);
            if (pSection == NULL)

            return FALSE;


            //
            // Check the section characteristics to see if the target address is
            // located within a writable section, returning a failure if yes.
            //
            return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;

            __except (GetExceptionCode() == STATUS_ACCESS_VIOLATION)

            //
            // Just return failure if the PE image is corrupted in any way that
            // triggers an AV.
            //
            return FALSE;




            At the top of the file there is code declaring this variable as extern:



            #if defined (_WIN64) && defined (_M_IA64)
            #pragma section(".base", long, read)
            __declspec(allocate(".base"))
            extern IMAGE_DOS_HEADER __ImageBase;
            #else /* defined (_WIN64) && defined (_M_IA64) */
            extern IMAGE_DOS_HEADER __ImageBase;
            #endif /* defined (_WIN64) && defined (_M_IA64) */


            So it may be that the key is the .base section and not the variable name by itself.






            share|improve this answer
























              up vote
              1
              down vote













              If you use Visual C++, you can use the special symbol __ImageBase which points to image base of the current module. For example, here's code from VS2010 CRT source (pesect.c):



              BOOL __cdecl _IsNonwritableInCurrentImage(
              PBYTE pTarget
              )

              PBYTE pImageBase;
              DWORD_PTR rvaTarget;
              PIMAGE_SECTION_HEADER pSection;

              pImageBase = (PBYTE)&__ImageBase;

              __try
              //
              // Make sure __ImageBase does address a PE image. This is likely an
              // unnecessary check, since we should be running from a normal image,
              // but it is fast, this routine is rarely called, and the normal call
              // is for security purposes. If we don't have a PE image, return
              // failure.
              //
              if (!_ValidateImageBase(pImageBase))

              return FALSE;


              //
              // Convert the targetaddress to a Relative Virtual Address (RVA) within
              // the image, and find the corresponding PE section. Return failure if
              // the target address is not found within the current image.
              //
              rvaTarget = pTarget - pImageBase;
              pSection = _FindPESection(pImageBase, rvaTarget);
              if (pSection == NULL)

              return FALSE;


              //
              // Check the section characteristics to see if the target address is
              // located within a writable section, returning a failure if yes.
              //
              return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;

              __except (GetExceptionCode() == STATUS_ACCESS_VIOLATION)

              //
              // Just return failure if the PE image is corrupted in any way that
              // triggers an AV.
              //
              return FALSE;




              At the top of the file there is code declaring this variable as extern:



              #if defined (_WIN64) && defined (_M_IA64)
              #pragma section(".base", long, read)
              __declspec(allocate(".base"))
              extern IMAGE_DOS_HEADER __ImageBase;
              #else /* defined (_WIN64) && defined (_M_IA64) */
              extern IMAGE_DOS_HEADER __ImageBase;
              #endif /* defined (_WIN64) && defined (_M_IA64) */


              So it may be that the key is the .base section and not the variable name by itself.






              share|improve this answer






















                up vote
                1
                down vote










                up vote
                1
                down vote









                If you use Visual C++, you can use the special symbol __ImageBase which points to image base of the current module. For example, here's code from VS2010 CRT source (pesect.c):



                BOOL __cdecl _IsNonwritableInCurrentImage(
                PBYTE pTarget
                )

                PBYTE pImageBase;
                DWORD_PTR rvaTarget;
                PIMAGE_SECTION_HEADER pSection;

                pImageBase = (PBYTE)&__ImageBase;

                __try
                //
                // Make sure __ImageBase does address a PE image. This is likely an
                // unnecessary check, since we should be running from a normal image,
                // but it is fast, this routine is rarely called, and the normal call
                // is for security purposes. If we don't have a PE image, return
                // failure.
                //
                if (!_ValidateImageBase(pImageBase))

                return FALSE;


                //
                // Convert the targetaddress to a Relative Virtual Address (RVA) within
                // the image, and find the corresponding PE section. Return failure if
                // the target address is not found within the current image.
                //
                rvaTarget = pTarget - pImageBase;
                pSection = _FindPESection(pImageBase, rvaTarget);
                if (pSection == NULL)

                return FALSE;


                //
                // Check the section characteristics to see if the target address is
                // located within a writable section, returning a failure if yes.
                //
                return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;

                __except (GetExceptionCode() == STATUS_ACCESS_VIOLATION)

                //
                // Just return failure if the PE image is corrupted in any way that
                // triggers an AV.
                //
                return FALSE;




                At the top of the file there is code declaring this variable as extern:



                #if defined (_WIN64) && defined (_M_IA64)
                #pragma section(".base", long, read)
                __declspec(allocate(".base"))
                extern IMAGE_DOS_HEADER __ImageBase;
                #else /* defined (_WIN64) && defined (_M_IA64) */
                extern IMAGE_DOS_HEADER __ImageBase;
                #endif /* defined (_WIN64) && defined (_M_IA64) */


                So it may be that the key is the .base section and not the variable name by itself.






                share|improve this answer












                If you use Visual C++, you can use the special symbol __ImageBase which points to image base of the current module. For example, here's code from VS2010 CRT source (pesect.c):



                BOOL __cdecl _IsNonwritableInCurrentImage(
                PBYTE pTarget
                )

                PBYTE pImageBase;
                DWORD_PTR rvaTarget;
                PIMAGE_SECTION_HEADER pSection;

                pImageBase = (PBYTE)&__ImageBase;

                __try
                //
                // Make sure __ImageBase does address a PE image. This is likely an
                // unnecessary check, since we should be running from a normal image,
                // but it is fast, this routine is rarely called, and the normal call
                // is for security purposes. If we don't have a PE image, return
                // failure.
                //
                if (!_ValidateImageBase(pImageBase))

                return FALSE;


                //
                // Convert the targetaddress to a Relative Virtual Address (RVA) within
                // the image, and find the corresponding PE section. Return failure if
                // the target address is not found within the current image.
                //
                rvaTarget = pTarget - pImageBase;
                pSection = _FindPESection(pImageBase, rvaTarget);
                if (pSection == NULL)

                return FALSE;


                //
                // Check the section characteristics to see if the target address is
                // located within a writable section, returning a failure if yes.
                //
                return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;

                __except (GetExceptionCode() == STATUS_ACCESS_VIOLATION)

                //
                // Just return failure if the PE image is corrupted in any way that
                // triggers an AV.
                //
                return FALSE;




                At the top of the file there is code declaring this variable as extern:



                #if defined (_WIN64) && defined (_M_IA64)
                #pragma section(".base", long, read)
                __declspec(allocate(".base"))
                extern IMAGE_DOS_HEADER __ImageBase;
                #else /* defined (_WIN64) && defined (_M_IA64) */
                extern IMAGE_DOS_HEADER __ImageBase;
                #endif /* defined (_WIN64) && defined (_M_IA64) */


                So it may be that the key is the .base section and not the variable name by itself.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 15 mins ago









                Igor Skochinsky♦

                23.2k34186




                23.2k34186




















                    Jason is a new contributor. Be nice, and check out our Code of Conduct.









                     

                    draft saved


                    draft discarded


















                    Jason is a new contributor. Be nice, and check out our Code of Conduct.












                    Jason is a new contributor. Be nice, and check out our Code of Conduct.











                    Jason is a new contributor. Be nice, and check out our Code of Conduct.













                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2freverseengineering.stackexchange.com%2fquestions%2f19660%2fis-there-any-way-to-get-my-own-image-base-without-calling-any-winapi-functions%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Comments

                    Popular posts from this blog

                    What does second last employer means? [closed]

                    Installing NextGIS Connect into QGIS 3?

                    One-line joke