iPXE
Defines | Functions
biosint.h File Reference
#include <realmode.h>

Go to the source code of this file.

Defines

#define hooked_bios_interrupts   __use_text16 ( hooked_bios_interrupts )

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
uint16_t __text16 (hooked_bios_interrupts)
 Hooked interrupt count.
void hook_bios_interrupt (unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
 Hook INT vector.
int unhook_bios_interrupt (unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
 Unhook INT vector.
void check_bios_interrupts (void)
 Dump changes to interrupt vector table (for debugging)

Define Documentation


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

Hooked interrupt count.

At exit, after unhooking all possible interrupts, this counter should be examined. If it is non-zero, it means that we failed to unhook at least one interrupt vector, and so must not free up the memory we are using. (Note that this also implies that we should re-hook INT 15 in order to hide ourselves from the memory map).

void hook_bios_interrupt ( unsigned int  interrupt,
unsigned int  handler,
struct segoff chain_vector 
)

Hook INT vector.

Parameters:
interruptINT number
handlerOffset within .text16 to interrupt handler
chain_vectorVector for chaining to previous handler

Hooks in an i386 INT handler. The handler itself must reside within the .text16 segment. chain_vector will be filled in with the address of the previously-installed handler for this interrupt; the handler should probably exit by ljmping via this vector.

Definition at line 24 of file biosint.c.

References code, copy_from_real, copy_to_real, DBG, DBG_HDA, DBG_LOG, hooked_bios_interrupts, segoff::offset, rm_cs, and segoff::segment.

Referenced by bios_inject_startup(), call_bootsector(), fake_e820(), hide_etherboot(), hook_comboot_interrupts(), int13_hook_vector(), pxe_activate(), rtc_hook_isr(), and undinet_hook_isr().

                                                         {
        struct segoff vector = {
                .segment = rm_cs,
                .offset = handler,
        };

        DBG ( "Hooking INT %#02x to %04x:%04x\n",
              interrupt, rm_cs, handler );

        if ( ( chain_vector->segment != 0 ) ||
             ( chain_vector->offset != 0 ) ) {
                /* Already hooked; do nothing */
                DBG ( "...already hooked\n" );
                return;
        }

        copy_from_real ( chain_vector, 0, ( interrupt * 4 ),
                         sizeof ( *chain_vector ) );
        DBG ( "...chaining to %04x:%04x\n",
              chain_vector->segment, chain_vector->offset );
        if ( DBG_LOG ) {
                char code[64];
                copy_from_real ( code, chain_vector->segment,
                                 chain_vector->offset, sizeof ( code ) );
                DBG_HDA ( *chain_vector, code, sizeof ( code ) );
        }

        copy_to_real ( 0, ( interrupt * 4 ), &vector, sizeof ( vector ) );
        hooked_bios_interrupts++;
}
int unhook_bios_interrupt ( unsigned int  interrupt,
unsigned int  handler,
struct segoff chain_vector 
)

Unhook INT vector.

Parameters:
interruptINT number
handlerOffset within .text16 to interrupt handler
chain_vectorVector containing address of previous handler

Unhooks an i386 interrupt handler hooked by hook_i386_vector(). Note that this operation may fail, if some external code has hooked the vector since we hooked in our handler. If it fails, it means that it is not possible to unhook our handler, and we must leave it (and its chaining vector) resident in memory.

Definition at line 69 of file biosint.c.

References copy_from_real, copy_to_real, DBG, EBUSY, hooked_bios_interrupts, segoff::offset, rm_cs, and segoff::segment.

Referenced by bios_inject_shutdown(), call_bootsector(), int13_unhook_vector(), pxe_deactivate(), rtc_unhook_isr(), undinet_unhook_isr(), unfake_e820(), unhide_etherboot(), and unhook_comboot_interrupts().

                                                          {
        struct segoff vector;

        DBG ( "Unhooking INT %#02x from %04x:%04x\n",
              interrupt, rm_cs, handler );

        copy_from_real ( &vector, 0, ( interrupt * 4 ), sizeof ( vector ) );
        if ( ( vector.segment != rm_cs ) || ( vector.offset != handler ) ) {
                DBG ( "...cannot unhook; vector points to %04x:%04x\n",
                      vector.segment, vector.offset );
                return -EBUSY;
        }

        DBG ( "...restoring to %04x:%04x\n",
              chain_vector->segment, chain_vector->offset );
        copy_to_real ( 0, ( interrupt * 4 ), chain_vector,
                       sizeof ( *chain_vector ) );

        chain_vector->segment = 0;
        chain_vector->offset = 0;
        hooked_bios_interrupts--;
        return 0;
}
void check_bios_interrupts ( void  )

Dump changes to interrupt vector table (for debugging)

Definition at line 98 of file biosint.c.

References copy_from_real, dbg_printf(), memcmp(), memcpy(), segoff::offset, offset, segoff::segment, and segment.

                                    {
        static struct segoff vectors[256];
        static uint8_t initialised;
        struct segoff vector;
        unsigned int i;

        /* Print any changed interrupt vectors */
        for ( i = 0; i < ( sizeof ( vectors ) / sizeof ( vectors[0] ) ); i++ ) {
                copy_from_real ( &vector, 0, ( i * sizeof ( vector ) ),
                                 sizeof ( vector ) );
                if ( memcmp ( &vector, &vectors[i], sizeof ( vector ) ) == 0 )
                        continue;
                if ( initialised ) {
                        dbg_printf ( "INT %02x changed %04x:%04x => "
                                     "%04x:%04x\n", i, vectors[i].segment,
                                     vectors[i].offset, vector.segment,
                                     vector.offset );
                }
                memcpy ( &vectors[i], &vector, sizeof ( vectors[i] ) );
        }
        initialised = 1;
}