"Bibliothek" für Stackabbildung - Erfahrungssammeln



  • Hallo, ich möchte euch einen Code zeigen, um eure Meinungen (Kritik) zu sammeln.

    Es handelt sich um eine "Bibliothek", die das Stack von einer Funktion auf einen Classobject abbildet. Sie lässt eigene Namen für die Variables, Arguments und Registers zu geben. Außerdem ist es möglich Kontext (context) zwischen den Funktionsrufen zu halten..

    Danke im Voraus 🙂

    aufführendes Beispiel :
    http://liveworkspace.org/code/3f845f505676439f912508bdbde0e95d

    "Bibliothek" :

    //
    
    namespace lib3 {
    
    struct regs 
    {
      struct edi {  unsigned long edi; };
      struct esi {  unsigned long esi; };
      struct ebp {  unsigned long ebp; };
      struct esp {  unsigned long esp; };
      struct ebx {  unsigned long ebx; };
      struct edx {  unsigned long edx; };
      struct ecx {  unsigned long ecx; };
      struct eax {  unsigned long eax; };
    
    };
    
    template<typename Regs = regs>
    struct rall // regs_struct
       : Regs::edi 
       , Regs::esi
       , Regs::ebp
       , Regs::esp
       , Regs::ebx
       , Regs::edx 
       , Regs::ecx 
       , Regs::eax
    { 
       template <class ARegs>
       operator rall<ARegs> const& () const
       {
             return *reinterpret_cast<const rall<ARegs>*>(this);       
       }
       template <class ARegs>
       operator rall<ARegs> & ()
       {
             return *reinterpret_cast<rall<ARegs>*>(this);       
       }   
    
    };
    
    struct ebp_tag {};
    struct esp_tag {};
    
    struct scope 
    {
       typedef ebp_tag   ebp;
       typedef esp_tag   esp;   
    
       enum { offset = 0 };
    
       struct vars      {            };
       struct esp_saved { long esp;  };
       struct ret_saved { long ret;  };  
       struct args      {            };
    };
    
    template <typename Scope>
    struct ebp_stack   
       : Scope::vars
       , Scope::esp_saved 
       , Scope::ret_saved
       , Scope::args
    {};
    
    template <typename Scope>
    struct esp_stack   
       : Scope::vars
       , Scope::ret_saved
       , Scope::args
    {};
    
    template <typename Scope, typename AddrTag >
    struct stack_kind {};
    
    template <typename Scope >
    struct stack_kind<Scope, ebp_tag >
    {
       typedef  ebp_stack<Scope> type;
    };
    
    template <typename Scope >
    struct stack_kind<Scope, esp_tag > 
    {
       typedef  esp_stack<Scope> type;
    };
    
    template <typename Scope>
    struct cut : stack_kind<Scope, typename Scope::addr_reg>::type {};
    
    template <typename Scope>
    unsigned long calc_addr (rall<> const&  r, esp_stack<Scope>*)
    {
         return r.esp + Scope::offset
              - sizeof (typename Scope::vars);
    
    }
    
    template <typename Scope>
    unsigned long calc_addr (rall<>  const&  r, ebp_stack<Scope>*)
    {
           return r.ebp + Scope::offset
                - sizeof (typename Scope::vars);         
    }
    
    template <typename Scope>
    cut<Scope>& get_cut (rall<> const& r) 
    { 
          return * static_cast<cut<Scope>*>
          (
             reinterpret_cast<void*>
             ( 
               calc_addr(r, (cut<Scope>*)0 )
             )
          );                              
    }
    
    struct auto_cut
    {
       auto_cut (rall<regs> const& r)
           : _regs(r) {}
    
       rall<regs> _regs;
    
       template <typename Scope>
       cut<Scope>& get () 
       { 
           return get_cut<Scope>(_regs);
       }
    
       template <typename Scope>
       operator cut<Scope>& () 
       { 
          return this->get<Scope>();
       }
    };
    
    } // namespace lib3
    

    Beispiel von einer "untersuchten" Funktion

    // 
    long some_fn(long asize) {
      long one, two;
      double three;
      one   = 0x11;
      two   = 0x12;
      three = 2.57;
    
        asm("mov $0x55, %esi");
        asm("mov $0x65, %ecx");
    
        asm("pusha"); //<: 1
        asm("call %P0" : : "i"(some_fn_cut));
        asm("popa");  //>: 1
    
      one   = 0x78;
      two   = 0x81;
      three = 16.79;    
    
        asm("pusha"); //<: 1
        asm("call %P0" : : "i"(some_fn_cut));
        asm("popa");  //>: 1
    
      return one + two + three;
    }
    

    Beispiel von einem Object der das Stack und Register obengezeigte Funktion druckt.

    struct some_fn {
    
       struct scope : lib3::scope {
    
          typedef ebp addr_reg;
    
    //     typedef esp addr_reg;
    //     enum { offset = 20 };
    
         struct vars  { double v3;
                        long   v2,
                               v1;
    
                      };
         struct args  { long   a1;   
                      };
       };  
    
      struct regs : lib3::regs  {
    
         struct ecx { long my_cx; }; 
         struct esi { long my_si; };     
    
      };
    
    // --
        some_fn () : _count(0) {} 
        long _count;
    
    //--       
    
       void operator () ( lib3::rall<regs> & r
                        , lib3::cut<scope> & s  ) 
       {      
          std::cout << std::hex
                    << "args: 0x" << s.a1 
                    << std::endl
                    << "vars: 0x" << s.v1 
                    << " 0x"     << s.v2 
                    << " "        << s.v3
                    << std::endl                  
                    << "regs: 0x" << r.my_si
                    << " 0x" << r.my_cx 
                    << std::endl          
    
                    ;                
          ++_count;
    
    //    dumpstack(r.esp, 40, r.ebp, s );         
       }
    
    };
    
    void some_fn_cut( lib3::rall<> r )
    {   
    
      printf ("test regs: %lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n\n",
                     r.edi, r.esi, r.ebp, r.esp, r.ebx, r.edx, r.ecx, r.eax
             );  
    
      static some_fn fn; fn (r, lib3::auto_cut ( r ) );
    
      printf ("exec_count: %lx \n\n", fn._count); 
    
    }
    

    main :

    int main ()
    {
      some_fn (0x14);
    }
    

    output:

    test regs: 0, 55, bfe9cfe8, bfe9cfd0, b6fd3ff4, 1, 65, bfe9d0a4

    args: 0x14
    vars: 0x11 0x12 2.57
    regs: 0x55 0x65
    exec_count: 1

    test regs: 0, 55, bfe9cfe8, bfe9cfd0, b6fd3ff4, 1, 65, bfe9d0a4

    args: 0x14
    vars: 0x78 0x81 16.79
    regs: 0x55 0x65
    exec_count: 2


Anmelden zum Antworten