Exemplo n.º 1
0
PSHORT
AllineaCh (PSHORT pCh, ULONG nByte, ULONG func)
{
  PBYTE pCh8 = NULL;
  ULONG pflag;
  ULONG psize;
  LONG p;
  APIRET rc;

  psize = (ULONG) &nByte;
  pflag = PAG_READ | PAG_WRITE | PAG_COMMIT;

  rc = DosQueryMem (pCh, &psize, &pflag);
  if (rc)
    {
      switch (rc)
	{
	case NO_ERROR:
	  break;
	case ERROR_INVALID_ADDRESS:
	  SendMsg (func, ERR_TRACCIA_ERRATA);
	  return 0;
	  break;
	default:
	  printf ("       DosQueryMem rc:%i\n", rc);
	  return 0;
	  break;
	}
    }

  p = (long) pCh *2;

  pCh = pCh + (nByte * 2) - 2;
  psize = (ULONG) &nByte;
  rc = DosQueryMem (pCh, &psize, &pflag);
  if (rc)
    {
      switch (rc)
	{
	case NO_ERROR:
	  break;
	case ERROR_INVALID_ADDRESS:
	  SendMsg (func, ERR_TRACCIA_INSUFFICIENTE);
	  return 0;
	  break;
	default:
	  printf ("       DosQueryMem rc:%i\n", rc);
	  return 0;
	  break;
	}
    }

  return (PSHORT) p;
}
Exemplo n.º 2
0
/*
 * Touches (reads/writes) the first word in every page of memory pointed to by
 * buf of len bytes. If buf is not on the page boundary, the word at buf is
 * touched instead. Note that the page is only touched if it's reserved (i.e.
 * neither committed, nor free).
 *
 * This function is used to work around a bug in DosRead that causes it to fail
 * when interrupted by the exception handler, see
 * https://github.com/bitwiseworks/libcx/issues/21.
 */
void touch_pages(void *buf, size_t len)
{
  APIRET arc;
  ULONG dos_len;
  ULONG dos_flags;

  volatile ULONG buf_addr = (ULONG)buf;
  ULONG buf_end = buf_addr + len;

  /*
   * Note: we need to at least perform the write operation when toucing so that
   * in case if it's our memory mapped region then it's marked dirty and with
   * PAG_WRITE is set (on read PAG_WRITE would have been removed whcih would
   * cause DosRead to fail too). And, to make sure that the touched region is
   * not corrupted by touching, we first read the target word and then simply
   * write it back.
   */

  if (!PAGE_ALIGNED(buf_addr))
  {
    dos_len = PAGE_SIZE;
    arc = DosQueryMem((PVOID)PAGE_ALIGN(buf_addr), &dos_len, &dos_flags);
    TRACE_IF(arc, "DosQueryMem = %lu\n", arc);
    if (!arc && !(dos_flags & (PAG_FREE | PAG_COMMIT)))
      *(int *)buf_addr = *(int *)buf_addr;
    buf_addr = PAGE_ALIGN(buf_addr) + PAGE_SIZE;
  }

  while (buf_addr < buf_end)
  {
    dos_len = ~0U;
    arc = DosQueryMem((PVOID)PAGE_ALIGN(buf_addr), &dos_len, &dos_flags);
    TRACE_IF(arc, "DosQueryMem = %lu\n", arc);
    if (!arc && !(dos_flags & (PAG_FREE | PAG_COMMIT)))
    {
      /* touch all pages within the reported range */
      dos_len += buf_addr;
      while (buf_addr < dos_len)
      {
        *(int *)buf_addr = *(int *)buf_addr;
        buf_addr += PAGE_SIZE;
      }
    }
    else
    {
      buf_addr += dos_len;
    }
  }
}
Exemplo n.º 3
0
VOID excDescribePage(FILE *file, ULONG ulCheck)
{
    APIRET arc;
    ULONG ulCountPages = 1;
    ULONG ulFlagsPage = 0;
    arc = DosQueryMem((PVOID)ulCheck, &ulCountPages, &ulFlagsPage);

    if (arc == NO_ERROR) {
        fprintf(file, "valid, flags: ");
        if (ulFlagsPage & PAG_READ)
            fprintf(file, "read ");
        if (ulFlagsPage & PAG_WRITE)
            fprintf(file, "write ");
        if (ulFlagsPage & PAG_EXECUTE)
            fprintf(file, "execute ");
        if (ulFlagsPage & PAG_GUARD)
            fprintf(file, "guard ");
        if (ulFlagsPage & PAG_COMMIT)
            fprintf(file, "committed ");
        if (ulFlagsPage & PAG_SHARED)
            fprintf(file, "shared ");
        if (ulFlagsPage & PAG_FREE)
            fprintf(file, "free ");
        if (ulFlagsPage & PAG_BASE)
            fprintf(file, "base ");
    }
    else if (arc == ERROR_INVALID_ADDRESS)
        fprintf(file, "invalid");
}
Exemplo n.º 4
0
ULONG APIENTRY  FileExceptionHandler( PEXCEPTIONREPORTRECORD pReport,
                             struct _EXCEPTIONREGISTRATIONRECORD * pXReg,
                             PCONTEXTRECORD pContext,
                             PVOID pDispatch)

{
    CAMJXRR *   pReg = (CAMJXRR*)pXReg;
    ULONG       ulRtn = XCPT_CONTINUE_SEARCH;
    ULONG       rc = 0;
    ULONG       ulSize;
    ULONG       ulAttr;
    LONG        lOffs;
    char *      pErr = 0;
    PVOID       pMem;

do {
    if (pReport->fHandlerFlags ||
        pReport->ExceptionNum     != XCPT_ACCESS_VIOLATION ||
        pReport->ExceptionAddress == (PVOID)XCPT_DATA_UNKNOWN ||
        pReport->ExceptionInfo[0] != XCPT_READ_ACCESS ||
        pReport->ExceptionInfo[1] == XCPT_DATA_UNKNOWN ||
        pReport->ExceptionInfo[1] <  (ULONG)pReg->pBase ||
        pReport->ExceptionInfo[1] >= (ULONG)pReg->pEnd) {
            printf( "*** Exception not handled - %08lx\n", pReport->ExceptionNum);
            return (ulRtn);
    }

    if (pReg->lFilePtr >= pReg->lEOF)
        ERRMSG( "already at EOF")

    pMem = (PVOID)(pReport->ExceptionInfo[1] & ~0xFFF);
    ulSize = 1;
    ulAttr = 0;

    rc = DosQueryMem( pMem, &ulSize, &ulAttr);
    if (rc)
        ERRMSG( "DosQueryMem")

    if (ulAttr & (PAG_FREE | PAG_COMMIT)) {
        rc = ulAttr;
        ERRMSG( "unexpected memory attributes")
    }

    rc = DosSetMem( pMem, 0x1000, PAG_COMMIT | PAG_DEFAULT);
    if (rc)
        ERRMSG( "DosSetMem")

    lOffs = (BYTE*)pMem - pReg->pBase;
    if (lOffs != pReg->lFilePtr) {
        rc = DosSetFilePtr( pReg->hFile, lOffs, FILE_BEGIN, &pReg->lFilePtr);
        if (rc)
            ERRMSG( "DosSetFilePtr")

        if (lOffs != pReg->lFilePtr) {
            rc = lOffs;
            ERRMSG( "seek beyond EOF")
        }
Exemplo n.º 5
0
/* to by the first entry point in a module */
void ForceModuleLoad(HMODULE hmodule)
{
  /* DosQueryMem */
  unsigned long memsize=0;
  unsigned long memend=0;
  unsigned long memflags=0;
  /* DosQueryProcAddr */
  PFN modaddr;

  volatile unsigned char cpybuf;
  unsigned int base=0;
  unsigned char* baseptr=0;

  if (DosQueryProcAddr(hmodule,1,0,&modaddr) == NO_ERROR) {
    /* calc 64K aligned addr previous to entry point */
    base=(( (unsigned long)modaddr) & 0xFFFF0000);
   
    /* get size and flags for this memory area */
    memsize=0x0fffffff;
    DosQueryMem((void*)base,&memsize,&memflags);
   
    /* if not first page of object, back off addr and retry */
    while (memflags < PAG_BASE) {
      base=base - PAG_BASE;
      memsize=0x0fffffff;
      DosQueryMem((void*)base,&memsize,&memflags);
    }
  
    /* finally, now loop through object pages, force page-in */
    memend=base+memsize;
    while(base<memend) {
      baseptr=(unsigned char*)base;
      cpybuf=*baseptr;
      base+=4096;
    }
  }
}
Exemplo n.º 6
0
static void
UnmapPages(void *addr, size_t size)
{
    if (!DosFreeMem(addr))
        return;

    /* if DosFreeMem() failed, 'addr' is probably part of an "expensive"
     * allocation, so calculate the base address and try again
     */
    unsigned long cb = 2 * size;
    unsigned long flags;
    if (DosQueryMem(addr, &cb, &flags) || cb < size)
        return;

    jsuword base = reinterpret_cast<jsuword>(addr) - ((2 * size) - cb);
    DosFreeMem(reinterpret_cast<void*>(base));

    return;
}
Exemplo n.º 7
0
static void *
MapAlignedPagesRecursively(size_t size, size_t alignment, int& recursions)
{
    if (++recursions >= OS2_MAX_RECURSIONS)
        return NULL;

    void *tmp;
    if (DosAllocMem(&tmp, size,
                    OBJ_ANY | PAG_COMMIT | PAG_READ | PAG_WRITE)) {
        JS_ALWAYS_TRUE(DosAllocMem(&tmp, size,
                                   PAG_COMMIT | PAG_READ | PAG_WRITE) == 0);
    }
    size_t offset = reinterpret_cast<jsuword>(tmp) & (alignment - 1);
    if (!offset)
        return tmp;

    /* if there are 'filler' bytes of free space above 'tmp', free 'tmp',
     * then reallocate it as a 'filler'-sized block;  assuming we're not
     * in a race with another thread, the next recursion should succeed
     */
    size_t filler = size + alignment - offset;
    unsigned long cb = filler;
    unsigned long flags = 0;
    unsigned long rc = DosQueryMem(&(static_cast<char*>(tmp))[size],
                                   &cb, &flags);
    if (!rc && (flags & PAG_FREE) && cb >= filler) {
        UnmapPages(tmp, 0);
        if (DosAllocMem(&tmp, filler,
                        OBJ_ANY | PAG_COMMIT | PAG_READ | PAG_WRITE)) {
            JS_ALWAYS_TRUE(DosAllocMem(&tmp, filler,
                                       PAG_COMMIT | PAG_READ | PAG_WRITE) == 0);
        }
    }

    void *p = MapAlignedPagesRecursively(size, alignment, recursions);
    UnmapPages(tmp, 0);

    return p;
}
/*
 * Exception handler; attempt to commit memory if access violation occures.
 */
static ULONG _System exception_handler(PEXCEPTIONREPORTRECORD pERepRec, PEXCEPTIONREGISTRATIONRECORD pERegRep, PCONTEXTRECORD pCtxRec, PVOID p)
{
   ULONG ulRet = XCPT_CONTINUE_EXECUTION;

   switch(pERepRec->ExceptionNum)
   {
      case XCPT_ACCESS_VIOLATION:
         ulRet = XCPT_CONTINUE_SEARCH;

         if(pERepRec->ExceptionAddress == (PVOID)XCPT_DATA_UNKNOWN)
         {
         }
         else
         {
            APIRET rc = NO_ERROR;
            ULONG cbMem = 1;
            ULONG flMem = 0;

            rc = DosQueryMem((PVOID)pERepRec->ExceptionInfo[1], &cbMem, &flMem);
            if((flMem & PAG_FREE) == 0)
            {
               rc = DosSetMem((PVOID)pERepRec->ExceptionInfo[1], 4096, PAG_DEFAULT | PAG_COMMIT);
               if(rc == NO_ERROR)
               {
                  ulRet = XCPT_CONTINUE_EXECUTION;
               }
            }
         }
         break;

      default:
         ulRet = XCPT_CONTINUE_SEARCH;
         break;
   }

   return ulRet;
}
Exemplo n.º 9
0
APR_DECLARE(apr_size_t) apr_shm_size_get(const apr_shm_t *m)
{
    ULONG flags, size = 0x1000000;
    DosQueryMem(m->memblock, &size, &flags);
    return size;
}
Exemplo n.º 10
0
VOID excExplainException(FILE *file,                   // in: logfile from fopen()
                         PSZ pszHandlerName,           // in: descriptive string
                         PEXCEPTIONREPORTRECORD pReportRec, // in: excpt info
                         PCONTEXTRECORD pContextRec)   // in: excpt info
{
    PTIB        ptib = NULL;
    PPIB        ppib = NULL;
    HMODULE     hMod1, hMod2;
    CHAR        szMod1[CCHMAXPATH] = "unknown",
                szMod2[CCHMAXPATH] = "unknown";
    ULONG       ulObjNum,
                ulOffset,
                ulCountPages,
                ulFlagsPage;
    APIRET      arc;
    PULONG      pulStackWord,
                pulStackBegin;
    ULONG       ul;

    ULONG       ulOldPriority = 0x0100; // regular, delta 0

    // raise this thread's priority, because this
    // might take some time
    if (DosGetInfoBlocks(&ptib, &ppib) == NO_ERROR)
        if (ptib)
            if (ptib->tib_ptib2) {
                ulOldPriority = ptib->tib_ptib2->tib2_ulpri;
                DosSetPriority(PRTYS_THREAD,
                        PRTYC_REGULAR,
                        PRTYD_MAXIMUM,
                        0);     // current thread
            }

    // make some noise
    DosBeep(4000, 30);
    DosBeep(2000, 30);
    DosBeep(1000, 30);
    DosBeep( 500, 30);
    DosBeep( 250, 30);
    DosBeep( 500, 30);
    DosBeep(1000, 30);
    DosBeep(2000, 30);
    DosBeep(4000, 30);

    // generic exception info
    fprintf(file,
            "\n%s:\n    Exception type: %08X\n    Address:        %08X\n    Params:         ",
            pszHandlerName,
            pReportRec->ExceptionNum,
            pReportRec->ExceptionAddress);
    for (ul = 0;  ul < pReportRec->cParameters;  ul++)
    {
        fprintf(file, "%08X  ",
            pReportRec->ExceptionInfo[ul]);
    }

    // now explain the exception in a bit more detail;
    // depending on the exception, pReportRec->ExceptionInfo
    // contains some useful data
    switch (pReportRec->ExceptionNum)
    {
        case XCPT_ACCESS_VIOLATION: {
            fprintf(file, "\nAccess violation: ");
            if (pReportRec->ExceptionInfo[0] & XCPT_READ_ACCESS)
                fprintf(file, "Invalid read access from 0x%04X:%08X.\n",
                            pContextRec->ctx_SegDs, pReportRec->ExceptionInfo[1]);
            else if (pReportRec->ExceptionInfo[0] & XCPT_WRITE_ACCESS)
                fprintf(file, "Invalid write access to 0x%04X:%08X.\n",
                            pContextRec->ctx_SegDs, pReportRec->ExceptionInfo[1]);
            else if (pReportRec->ExceptionInfo[0] & XCPT_SPACE_ACCESS)
                fprintf(file, "Invalid space access at 0x%04X.\n",
                            pReportRec->ExceptionInfo[1]);
            else if (pReportRec->ExceptionInfo[0] & XCPT_LIMIT_ACCESS)
                fprintf(file, "Invalid limit access occurred.\n");
            else if (pReportRec->ExceptionInfo[0] == XCPT_UNKNOWN_ACCESS)
                fprintf(file, "unknown at 0x%04X:%08X\n",
                            pContextRec->ctx_SegDs, pReportRec->ExceptionInfo[1]);
            fprintf(file,
                        "Explanation: An attempt was made to access a memory object which does\n"
                        "             not belong to the current process. Most probable causes\n"
                        "             for this are that an invalid pointer was used, there was\n"
                        "             confusion with administering memory or error conditions \n"
                        "             were not properly checked for.\n");
            break;
        }

        case XCPT_INTEGER_DIVIDE_BY_ZERO: {
            fprintf(file, "\nInteger division by zero.\n");
            fprintf(file,
                        "Explanation: An attempt was made to divide an integer value by zero,\n"
                        "             which is not defined.\n");
            break;
        }

        case XCPT_ILLEGAL_INSTRUCTION: {
            fprintf(file, "\nIllegal instruction found.\n");
            fprintf(file,
                        "Explanation: An attempt was made to execute an instruction that\n"
                        "             is not defined on this machine's architecture.\n");
            break;
        }

        case XCPT_PRIVILEGED_INSTRUCTION: {
            fprintf(file, "\nPrivileged instruction found.\n");
            fprintf(file,
                        "Explanation: An attempt was made to execute an instruction that\n"
                        "             is not permitted in the current machine mode or that\n"
                        "             XFolder had no permission to execute.\n");
            break;
        }

        case XCPT_INTEGER_OVERFLOW:
            fprintf(file, "\nInteger overflow.\n");
            fprintf(file,
                        "Explanation: An integer operation generated a carry-out of the most\n"
                        "             significant bit. This is a sign of an attempt to store\n"
                        "             a value which does not fit into an integer variable.\n");
    }

    if (DosGetInfoBlocks(&ptib, &ppib) == NO_ERROR)
    {
        /*
         * process info:
         *
         */

        if (ppib)
        {
            if (pContextRec->ContextFlags & CONTEXT_CONTROL)
            {
                // get the main module
                hMod1 = ppib->pib_hmte;
                DosQueryModuleName(hMod1,
                                   sizeof(szMod1),
                                   szMod1);

                // get the trapping module
                DosQueryModFromEIP(&hMod2,
                                   &ulObjNum,
                                   sizeof(szMod2),
                                   szMod2,
                                   &ulOffset,
                                   pContextRec->ctx_RegEip);
                DosQueryModuleName(hMod2,
                                   sizeof(szMod2),
                                   szMod2);
            }

            fprintf(file,
                    "\nProcess information: PID 0x%lX"
                    "\n    Module handle:   0x%lX (%s)"
                    "\n    Trapping module: 0x%lX (%s)"
                    "\n    Object: %d\n",
                    ppib->pib_ulpid,
                    hMod1, szMod1,
                    hMod2, szMod2,
                    ulObjNum);
        } else
            fprintf(file, "\nProcess information was not available.");



        // *** registers

        fprintf(file, "\nRegisters:");
        if (pContextRec->ContextFlags & CONTEXT_INTEGER)
        {
            // EAX
            fprintf(file, "\n    EAX = %08X  ", pContextRec->ctx_RegEax);
            excDescribePage(file, pContextRec->ctx_RegEax);
            // EBX
            fprintf(file, "\n    EBX = %08X  ", pContextRec->ctx_RegEbx);
            excDescribePage(file, pContextRec->ctx_RegEbx);
            // ECX
            fprintf(file, "\n    ECX = %08X  ", pContextRec->ctx_RegEcx);
            excDescribePage(file, pContextRec->ctx_RegEcx);
            // EDX
            fprintf(file, "\n    EDX = %08X  ", pContextRec->ctx_RegEdx);
            excDescribePage(file, pContextRec->ctx_RegEdx);
            // ESI
            fprintf(file, "\n    ESI = %08X  ", pContextRec->ctx_RegEsi);
            excDescribePage(file, pContextRec->ctx_RegEsi);
            // EDI
            fprintf(file, "\n    EDI = %08X  ", pContextRec->ctx_RegEdi);
            excDescribePage(file, pContextRec->ctx_RegEdi);
            fprintf(file, "\n");
        } else
            fprintf(file, " not available\n");

        if (pContextRec->ContextFlags & CONTEXT_CONTROL)
        {

            // *** instruction

            fprintf(file, "Instruction:\n    CS:EIP = %04X:%08X  ",
                    pContextRec->ctx_SegCs,
                    pContextRec->ctx_RegEip);
            excDescribePage(file, pContextRec->ctx_RegEip);

            // *** CPU flags

            fprintf(file, "\n    FLG    = %08X", pContextRec->ctx_EFlags);

            /*
             * stack:
             *
             */

            fprintf(file, "\nStack:\n    Base:         %08X\n    Limit:        %08X",
                (ptib ? ptib->tib_pstack : 0),
                (ptib ? ptib->tib_pstacklimit :0));
            fprintf(file, "\n    SS:ESP = %04X:%08X  ",
                pContextRec->ctx_SegSs, pContextRec->ctx_RegEsp);
            excDescribePage(file, pContextRec->ctx_RegEsp);

            fprintf(file, "\n    EBP    =      %08X  ", pContextRec->ctx_RegEbp);
            excDescribePage(file, pContextRec->ctx_RegEbp);

            dbgPrintStack(file,
                        (PUSHORT)ptib->tib_pstack,
                        (PUSHORT)ptib->tib_pstacklimit,
                        (PUSHORT)pContextRec->ctx_RegEbp,
                        (PUSHORT)pReportRec->ExceptionAddress);

            /*
             * stack dump:
             *      this code is mostly (W) Roman Stangl.
             */

            if (ptib != 0)
            {
                #ifdef DEBUG_EXCPT_STACKDUMP
                    // start with Stack dump; if EBP is within stack and smaller
                    // than ESP, use EBP, otherwise use ESP (which points into the
                    // stack anyway, so no check needed)
                    fprintf(file, "\n\nStack dump :      +0         +4         +8         +C");
                    if (pContextRec->ctx_RegEbp < pContextRec->ctx_RegEsp)
                        pulStackWord = (PULONG)(pContextRec->ctx_RegEbp & 0xFFFFFFF0);
                    else
                        pulStackWord = (PULONG)(pContextRec->ctx_RegEsp & 0xFFFFFFF0);

                    for (pulStackBegin = pulStackWord;
                         pulStackWord <= (PULONG)ptib->tib_pstacklimit;
                        /* NOP */)
                    {
                        if (((ULONG)pulStackWord & 0x00000FFF) == 0x00000000)
                        {
                            // we're on a page boundary: check access
                            ulCountPages = 0x1000;
                            ulFlagsPage = 0;
                            arc = DosQueryMem((void *)pulStackWord,
                                    &ulCountPages, &ulFlagsPage);
                            if (    (arc != NO_ERROR)
                                 || (   (arc == NO_ERROR)
                                      && ( !( ((ulFlagsPage & (PAG_COMMIT|PAG_READ))
                                            == (PAG_COMMIT|PAG_READ)) ) )
                                    )
                               )
                            {
                                fprintf(file, "\n    %08X: ", pulStackWord);
                                fprintf(file, "Page inaccessible");
                                pulStackWord += 0x1000;
                                continue; // for
                            }
                        }

                        if (((ULONG)pulStackWord & 0x0000000F) == 0)
                            fprintf(file, "\n    %08X: ", pulStackWord);
                        if (    (*pulStackWord >= (ULONG)pulStackBegin)
                             && (*pulStackWord <= (ULONG)ptib->tib_pstacklimit)
                           )
                            fprintf(file, "<%08X> ", *pulStackWord);
                        else
                            fprintf(file, " %08X  ", *pulStackWord);
                        pulStackWord++;
                    } // end for
                #endif

                // *** stack frames

                fprintf(file, "\n\nStack frames:\n              Address   Module:Object\n");
                pulStackWord = (PULONG)pContextRec->ctx_RegEbp;
                while (    (pulStackWord != 0)
                        && (pulStackWord < (PULONG)ptib->tib_pstacklimit)
                      )
                {
                    fprintf(file, "    %08X: %08X ",
                            pulStackWord,
                            *(pulStackWord+1));
                    if (DosQueryModFromEIP(&hMod1, &ulObjNum,
                                sizeof(szMod1), szMod1,
                                &ulOffset,
                                *(pulStackWord+1))
                       == NO_ERROR)
                    {
                        fprintf(file, " %s:%d\n",
                            szMod1, ulObjNum);
                    }
                    pulStackWord = (PULONG)*(pulStackWord);
                } // end while
            }
        }
    }
    fprintf(file, "\n");

    // reset old priority
    DosSetPriority(PRTYS_THREAD,
            (ulOldPriority & 0x0F00) >> 8,
            (UCHAR)ulOldPriority,
            0);     // current thread
}