/* * Initialize debugger back end modules */ static void initialize(JNIEnv *env, jthread thread, EventIndex triggering_ei) { jvmtiError error; EnumerateArg arg; jbyte suspendPolicy; LOG_MISC(("Begin initialize()")); currentSessionID = 0; initComplete = JNI_FALSE; if ( gdata->vmDead ) { EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at initialize() time"); } /* Turn off the initial JVMTI event notifications */ error = set_event_notification(JVMTI_DISABLE, EI_EXCEPTION); if (error != JVMTI_ERROR_NONE) { EXIT_ERROR(error, "unable to disable JVMTI event notification"); } error = set_event_notification(JVMTI_DISABLE, EI_VM_INIT); if (error != JVMTI_ERROR_NONE) { EXIT_ERROR(error, "unable to disable JVMTI event notification"); } error = set_event_notification(JVMTI_DISABLE, EI_VM_DEATH); if (error != JVMTI_ERROR_NONE) { EXIT_ERROR(error, "unable to disable JVMTI event notification"); } /* Remove initial event callbacks */ (void)memset(&(gdata->callbacks),0,sizeof(gdata->callbacks)); error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks) (gdata->jvmti, &(gdata->callbacks), sizeof(gdata->callbacks)); if (error != JVMTI_ERROR_NONE) { EXIT_ERROR(error, "unable to clear JVMTI callbacks"); } commonRef_initialize(); util_initialize(env); threadControl_initialize(); stepControl_initialize(); invoker_initialize(); debugDispatch_initialize(); classTrack_initialize(env); debugLoop_initialize(); initMonitor = debugMonitorCreate("JDWP Initialization Monitor"); /* * Initialize transports */ arg.isServer = isServer; arg.error = JDWP_ERROR(NONE); arg.startCount = 0; transport_initialize(); (void)bagEnumerateOver(transports, startTransport, &arg); /* * Exit with an error only if * 1) none of the transports was successfully started, and * 2) the application has not yet started running */ if ((arg.error != JDWP_ERROR(NONE)) && (arg.startCount == 0) && initOnStartup) { EXIT_ERROR(map2jvmtiError(arg.error), "No transports initialized"); } eventHandler_initialize(currentSessionID); signalInitComplete(); transport_waitForConnection(); suspendPolicy = suspendOnInit ? JDWP_SUSPEND_POLICY(ALL) : JDWP_SUSPEND_POLICY(NONE); if (triggering_ei == EI_VM_INIT) { LOG_MISC(("triggering_ei == EI_VM_INIT")); eventHelper_reportVMInit(env, currentSessionID, thread, suspendPolicy); } else { /* * TO DO: Kludgy way of getting the triggering event to the * just-attached debugger. It would be nice to make this a little * cleaner. There is also a race condition where other events * can get in the queue (from other not-yet-suspended threads) * before this one does. (Also need to handle allocation error below?) */ EventInfo info; struct bag *initEventBag; LOG_MISC(("triggering_ei != EI_VM_INIT")); initEventBag = eventHelper_createEventBag(); (void)memset(&info,0,sizeof(info)); info.ei = triggering_ei; eventHelper_recordEvent(&info, 0, suspendPolicy, initEventBag); (void)eventHelper_reportEvents(currentSessionID, initEventBag); bagDestroyBag(initEventBag); } if ( gdata->vmDead ) { EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead before initialize() completes"); } LOG_MISC(("End initialize()")); }
static jboolean parseOptions(char *options) { TransportSpec *currentTransport = NULL; char *end; char *current; int length; char *str; char *errmsg; /* Set defaults */ gdata->assertOn = DEFAULT_ASSERT_ON; gdata->assertFatal = DEFAULT_ASSERT_FATAL; logfile = DEFAULT_LOGFILE; /* Options being NULL will end up being an error. */ if (options == NULL) { options = ""; } /* Check for "help" BEFORE we add any environmental settings */ if ((strcmp(options, "help")) == 0) { printUsage(); forceExit(0); /* Kill entire process, no core dump wanted */ } /* These buffers are never freed */ { char *envOptions; /* * Add environmentally specified options. */ envOptions = getenv("_JAVA_JDWP_OPTIONS"); if (envOptions != NULL) { options = add_to_options(options, envOptions); if ( options==NULL ) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options"); } } /* * Allocate a buffer for names derived from option strings. It should * never be longer than the original options string itself. * Also keep a copy of the options in gdata->options. */ length = (int)strlen(options); gdata->options = jvmtiAllocate(length + 1); if (gdata->options == NULL) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options"); } (void)strcpy(gdata->options, options); names = jvmtiAllocate(length + 1); if (names == NULL) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options"); } transports = bagCreateBag(sizeof(TransportSpec), 3); if (transports == NULL) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"transports"); } } current = names; end = names + length; str = options; while (*str) { char buf[100]; /*LINTED*/ if (!get_tok(&str, buf, (int)sizeof(buf), '=')) { goto syntax_error; } if (strcmp(buf, "transport") == 0) { currentTransport = bagAdd(transports); /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } currentTransport->name = current; current += strlen(current) + 1; } else if (strcmp(buf, "address") == 0) { if (currentTransport == NULL) { errmsg = "address specified without transport"; goto bad_option_with_errmsg; } /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } currentTransport->address = current; current += strlen(current) + 1; } else if (strcmp(buf, "timeout") == 0) { if (currentTransport == NULL) { errmsg = "timeout specified without transport"; goto bad_option_with_errmsg; } /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } currentTransport->timeout = atol(current); current += strlen(current) + 1; } else if (strcmp(buf, "launch") == 0) { /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } launchOnInit = current; current += strlen(current) + 1; } else if (strcmp(buf, "onthrow") == 0) { /* Read class name and convert in place to a signature */ *current = 'L'; /*LINTED*/ if (!get_tok(&str, current + 1, (int)(end - current - 1), ',')) { goto syntax_error; } initOnException = current; while (*current != '\0') { if (*current == '.') { *current = '/'; } current++; } *current++ = ';'; *current++ = '\0'; } else if (strcmp(buf, "assert") == 0) { /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } if (strcmp(current, "y") == 0) { gdata->assertOn = JNI_TRUE; gdata->assertFatal = JNI_FALSE; } else if (strcmp(current, "fatal") == 0) { gdata->assertOn = JNI_TRUE; gdata->assertFatal = JNI_TRUE; } else if (strcmp(current, "n") == 0) { gdata->assertOn = JNI_FALSE; gdata->assertFatal = JNI_FALSE; } else { goto syntax_error; } current += strlen(current) + 1; } else if (strcmp(buf, "pause") == 0) { if ( !get_boolean(&str, &dopause) ) { goto syntax_error; } if ( dopause ) { do_pause(); } } else if (strcmp(buf, "coredump") == 0) { if ( !get_boolean(&str, &docoredump) ) { goto syntax_error; } } else if (strcmp(buf, "errorexit") == 0) { if ( !get_boolean(&str, &(gdata->doerrorexit)) ) { goto syntax_error; } } else if (strcmp(buf, "exitpause") == 0) { errmsg = "The exitpause option removed, use -XX:OnError"; goto bad_option_with_errmsg; } else if (strcmp(buf, "precrash") == 0) { errmsg = "The precrash option removed, use -XX:OnError"; goto bad_option_with_errmsg; } else if (strcmp(buf, "logfile") == 0) { /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } logfile = current; current += strlen(current) + 1; } else if (strcmp(buf, "logflags") == 0) { /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } /*LINTED*/ logflags = (unsigned)strtol(current, NULL, 0); } else if (strcmp(buf, "debugflags") == 0) { /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } /*LINTED*/ gdata->debugflags = (unsigned)strtol(current, NULL, 0); } else if ( strcmp(buf, "suspend")==0 ) { if ( !get_boolean(&str, &suspendOnInit) ) { goto syntax_error; } } else if ( strcmp(buf, "server")==0 ) { if ( !get_boolean(&str, &isServer) ) { goto syntax_error; } } else if ( strcmp(buf, "strict")==0 ) { /* Obsolete, but accept it */ if ( !get_boolean(&str, &isStrict) ) { goto syntax_error; } } else if ( strcmp(buf, "quiet")==0 ) { if ( !get_boolean(&str, &(gdata->quiet)) ) { goto syntax_error; } } else if ( strcmp(buf, "onuncaught")==0 ) { if ( !get_boolean(&str, &initOnUncaught) ) { goto syntax_error; } } else if ( strcmp(buf, "mutf8")==0 ) { if ( !get_boolean(&str, &(gdata->modifiedUtf8)) ) { goto syntax_error; } } else if ( strcmp(buf, "stdalloc")==0 ) { /* Obsolete, but accept it */ if ( !get_boolean(&str, &useStandardAlloc) ) { goto syntax_error; } } else { goto syntax_error; } } /* Setup logging now */ if ( logfile!=NULL ) { setup_logging(logfile, logflags); (void)atexit(&atexit_finish_logging); } if (bagSize(transports) == 0) { errmsg = "no transport specified"; goto bad_option_with_errmsg; } /* * TO DO: Remove when multiple transports are allowed. (replace with * check below. */ if (bagSize(transports) > 1) { errmsg = "multiple transports are not supported in this release"; goto bad_option_with_errmsg; } if (!isServer) { jboolean specified = bagEnumerateOver(transports, checkAddress, NULL); if (!specified) { /* message already printed */ goto bad_option_no_msg; } } /* * The user has selected to wait for an exception before init happens */ if ((initOnException != NULL) || (initOnUncaught)) { initOnStartup = JNI_FALSE; if (launchOnInit == NULL) { /* * These rely on the launch=/usr/bin/foo * suboption, so it is an error if user did not * provide one. */ errmsg = "Specify launch=<command line> when using onthrow or onuncaught suboption"; goto bad_option_with_errmsg; } } return JNI_TRUE; syntax_error: ERROR_MESSAGE(("JDWP option syntax error: %s=%s", AGENTLIB, options)); return JNI_FALSE; bad_option_with_errmsg: ERROR_MESSAGE(("JDWP %s: %s=%s", errmsg, AGENTLIB, options)); return JNI_FALSE; bad_option_no_msg: ERROR_MESSAGE(("JDWP %s: %s=%s", "invalid option", AGENTLIB, options)); return JNI_FALSE; }
static void JNICALL cbEarlyException(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jmethodID method, jlocation location, jobject exception, jmethodID catch_method, jlocation catch_location) { jvmtiError error; jthrowable currentException; LOG_CB(("cbEarlyException: thread=%p", thread)); if ( gdata->vmDead ) { EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at initial Exception event"); } if (!vmInitialized) { LOG_MISC(("VM is not initialized yet")); return; } /* * We want to preserve any current exception that might get wiped * out during event handling (e.g. JNI calls). We have to rely on * space for the local reference on the current frame because * doing a PushLocalFrame here might itself generate an exception. */ currentException = JNI_FUNC_PTR(env,ExceptionOccurred)(env); JNI_FUNC_PTR(env,ExceptionClear)(env); if (initOnUncaught && catch_method == NULL) { LOG_MISC(("Initializing on uncaught exception")); initialize(env, thread, EI_EXCEPTION); } else if (initOnException != NULL) { jclass clazz; /* Get class of exception thrown */ clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, exception); if ( clazz != NULL ) { char *signature = NULL; /* initing on throw, check */ error = classSignature(clazz, &signature, NULL); LOG_MISC(("Checking specific exception: looking for %s, got %s", initOnException, signature)); if ( (error==JVMTI_ERROR_NONE) && (strcmp(signature, initOnException) == 0)) { LOG_MISC(("Initializing on specific exception")); initialize(env, thread, EI_EXCEPTION); } else { error = AGENT_ERROR_INTERNAL; /* Just to cause restore */ } if ( signature != NULL ) { jvmtiDeallocate(signature); } } else { error = AGENT_ERROR_INTERNAL; /* Just to cause restore */ } /* If initialize didn't happen, we need to restore things */ if ( error != JVMTI_ERROR_NONE ) { /* * Restore exception state from before callback call */ LOG_MISC(("No initialization, didn't find right exception")); if (currentException != NULL) { JNI_FUNC_PTR(env,Throw)(env, currentException); } else { JNI_FUNC_PTR(env,ExceptionClear)(env); } } } LOG_MISC(("END cbEarlyException")); }
int main (int argc, const char **argv) { Param_t *param = NULL; Input_t *input = NULL; Lut_t *lut = NULL; Output_t *output = NULL; Output_t *output_th = NULL; int iline, isamp,oline, ib, jb, iz, val; unsigned char *line_in = NULL; unsigned char *line_in_thz = NULL; unsigned char *line_out_qa = NULL; int16 *line_out = NULL; int16 *line_out_th = NULL; int16 *line_out_thz = NULL; Cal_stats_t cal_stats; Cal_stats6_t cal_stats6; int nps,nls, nps6, nls6; int zoomx, zoomy; int i,odometer_flag=0; char msgbuf[1024]; char envi_file[STR_SIZE]; /* name of the output ENVI header file */ char *cptr=NULL; /* pointer to the file extension */ size_t input_psize; int qa_band = QA_BAND_NUM; int nband_refl = NBAND_REFL_MAX; int ifill, num_zero; int maxth=0; int mss_flag=0; Espa_internal_meta_t xml_metadata; /* XML metadata structure */ Envi_header_t envi_hdr; /* output ENVI header information */ printf ("\nRunning lndcal ...\n"); for (i=1; i<argc; i++)if ( !strcmp(argv[i],"-o") )odometer_flag=1; /* Read the parameters from the input parameter file */ param = GetParam(argc, argv); if (param == (Param_t *)NULL) EXIT_ERROR("getting runtime parameters", "main"); /* Validate the input metadata file */ if (validate_xml_file (param->input_xml_file_name) != SUCCESS) { /* Error messages already written */ EXIT_ERROR("Failure validating XML file", "main"); } /* Initialize the metadata structure */ init_metadata_struct (&xml_metadata); /* Parse the metadata file into our internal metadata structure; also allocates space as needed for various pointers in the global and band metadata */ if (parse_metadata (param->input_xml_file_name, &xml_metadata) != SUCCESS) { /* Error messages already written */ EXIT_ERROR("parsing XML file", "main"); } /* Check to see if the gain and bias values were specified */ if (!existRadGB (&xml_metadata)) EXIT_ERROR("Gains and biases don't exist in XML file (TOA radiance gain " "and bias fields) for each band. Make sure to utilize the latest LPGS " "MTL file for conversion to the ESPA internal raw binary format as the " "gains and biases should be in that file.", "main"); /* Open input file */ input = OpenInput (&xml_metadata); if (input == (Input_t *)NULL) EXIT_ERROR("setting up input from XML structure", "main"); /* Get Lookup table */ lut = GetLut(param, input->nband, input); if (lut == (Lut_t *)NULL) EXIT_ERROR("bad lut file", "main"); nps6= input->size_th.s; nls6= input->size_th.l; nps = input->size.s; nls = input->size.l; zoomx= nint( (float)nps / (float)nps6 ); zoomy= nint( (float)nls / (float)nls6 ); for (ib = 0; ib < input->nband; ib++) cal_stats.first[ib] = true; cal_stats6.first = true; if (input->meta.inst == INST_MSS)mss_flag=1; /* Open the output files. Raw binary band files will be be opened. */ output = OpenOutput(&xml_metadata, input, param, lut, false /*not thermal*/, mss_flag); if (output == NULL) EXIT_ERROR("opening output file", "main"); /* Allocate memory for the input buffer, enough for all reflectance bands */ input_psize = sizeof(unsigned char); line_in = calloc (input->size.s * nband_refl, input_psize); if (line_in == NULL) EXIT_ERROR("allocating input line buffer", "main"); /* Create and open output thermal band, if one exists */ if ( input->nband_th > 0 ) { output_th = OpenOutput (&xml_metadata, input, param, lut, true /*thermal*/, mss_flag); if (output_th == NULL) EXIT_ERROR("opening output therm file", "main"); /* Allocate memory for the thermal input and output buffer, only holds one band */ line_out_th = calloc(input->size_th.s, sizeof(int16)); if (line_out_th == NULL) EXIT_ERROR("allocating thermal output line buffer", "main"); if (zoomx == 1) { line_out_thz = line_out_th; line_in_thz = line_in; } else { line_out_thz = calloc (input->size.s, sizeof(int16)); if (line_out_thz == NULL) EXIT_ERROR("allocating thermal zoom output line buffer", "main"); line_in_thz = calloc (input->size.s, input_psize); if (line_in_thz == NULL) EXIT_ERROR("allocating thermal zoom input line buffer", "main"); } } else { printf("*** no output thermal file ***\n"); } /* Allocate memory for output lines for both the image and QA data */ line_out = calloc (input->size.s, sizeof (int16)); if (line_out == NULL) EXIT_ERROR("allocating output line buffer", "main"); line_out_qa = calloc (input->size.s, sizeof(unsigned char)); if (line_out_qa == NULL) EXIT_ERROR("allocating qa output line buffer", "main"); memset (line_out_qa, 0, input->size.s * sizeof(unsigned char)); /* Do for each THERMAL line */ oline= 0; if (input->nband_th > 0) { ifill= (int)lut->in_fill; for (iline = 0; iline < input->size_th.l; iline++) { ib=0; if (!GetInputLineTh(input, iline, line_in)) EXIT_ERROR("reading input data for a line", "main"); if ( odometer_flag && ( iline==0 || iline ==(nls-1) || iline%100==0 ) ){ if ( zoomy == 1 ) printf("--- main loop BAND6 Line %d --- \r",iline); else printf("--- main loop BAND6 Line in=%d out=%d --- \r",iline,oline); fflush(stdout); } memset(line_out_qa, 0, input->size.s*sizeof(unsigned char)); if (!Cal6(lut, input, line_in, line_out_th, line_out_qa, &cal_stats6, iline)) EXIT_ERROR("doing calibration for a line", "main"); if ( zoomx>1 ) { zoomIt(line_out_thz, line_out_th, nps/zoomx, zoomx ); zoomIt8(line_in_thz, line_in, nps/zoomx, zoomx ); } for ( iz=0; iz<zoomy; iz++ ) { for (isamp = 0; isamp < input->size.s; isamp++) { val= getValue(line_in_thz, isamp); if ( val> maxth) maxth=val; if ( val==ifill) line_out_qa[isamp] = lut->qa_fill; else if ( val>=SATU_VAL6 ) line_out_qa[isamp] = ( 0x000001 << 6 ); } if ( oline<nls ) { if (!PutOutputLine(output_th, ib, oline, line_out_thz)) { sprintf(msgbuf,"write thermal error ib=%d oline=%d iline=%d",ib, oline,iline); EXIT_ERROR(msgbuf, "main"); } if (input->meta.inst != INST_MSS) if (!PutOutputLine(output_th, ib+1, oline, line_out_qa)) { sprintf(msgbuf,"write thermal QA error ib=%d oline=%d iline=%d", ib+1,oline,iline); EXIT_ERROR(msgbuf, "main"); } } oline++; } } /* end loop for each thermal line */ } if (odometer_flag) printf("\n"); if (input->nband_th > 0) if (!CloseOutput(output_th)) EXIT_ERROR("closing output thermal file", "main"); /* Do for each REFLECTIVE line */ ifill= (int)lut->in_fill; for (iline = 0; iline < input->size.l; iline++){ /* Do for each band */ if ( odometer_flag && ( iline==0 || iline ==(nls-1) || iline%100==0 ) ) {printf("--- main reflective loop Line %d ---\r",iline); fflush(stdout);} memset(line_out_qa, 0, input->size.s*sizeof(unsigned char)); for (ib = 0; ib < input->nband; ib++) { if (!GetInputLine(input, ib, iline, &line_in[ib*nps])) EXIT_ERROR("reading input data for a line", "main"); } for (isamp = 0; isamp < input->size.s; isamp++){ num_zero=0; for (ib = 0; ib < input->nband; ib++) { jb= (ib != 5 ) ? ib+1 : ib+2; val= getValue((unsigned char *)&line_in[ib*nps], isamp); if ( val==ifill )num_zero++; if ( val==SATU_VAL[ib] ) line_out_qa[isamp]|= ( 0x000001 <<jb ); } /* Feng fixed bug by changing "|=" to "=" below (4/17/09) */ if ( num_zero > 0 )line_out_qa[isamp] = lut->qa_fill; } for (ib = 0; ib < input->nband; ib++) { if (!Cal(lut, ib, input, &line_in[ib*nps], line_out, line_out_qa, &cal_stats,iline)) EXIT_ERROR("doing calibraton for a line", "main"); if (!PutOutputLine(output, ib, iline, line_out)) EXIT_ERROR("reading input data for a line", "main"); } /* End loop for each band */ if (input->meta.inst != INST_MSS) if (!PutOutputLine(output, qa_band, iline, line_out_qa)) EXIT_ERROR("writing qa data for a line", "main"); } /* End loop for each line */ if ( odometer_flag )printf("\n"); for (ib = 0; ib < input->nband; ib++) { printf( " band %d rad min %8.5g max %8.4f | ref min %8.5f max %8.4f\n", input->meta.iband[ib], cal_stats.rad_min[ib], cal_stats.rad_max[ib], cal_stats.ref_min[ib], cal_stats.ref_max[ib]); } if ( input->nband_th > 0 ) printf( " band %d rad min %8.5g max %8.4f | tmp min %8.5f max %8.4f\n", 6, cal_stats6.rad_min, cal_stats6.rad_max, cal_stats6.temp_min, cal_stats6.temp_max); /* Close input and output files */ if (!CloseInput(input)) EXIT_ERROR("closing input file", "main"); if (!CloseOutput(output)) EXIT_ERROR("closing input file", "main"); /* Write the ENVI header for reflectance files */ for (ib = 0; ib < output->nband; ib++) { /* Create the ENVI header file this band */ if (create_envi_struct (&output->metadata.band[ib], &xml_metadata.global, &envi_hdr) != SUCCESS) EXIT_ERROR("Creating the ENVI header structure for this file.", "main"); /* Write the ENVI header */ strcpy (envi_file, output->metadata.band[ib].file_name); cptr = strchr (envi_file, '.'); strcpy (cptr, ".hdr"); if (write_envi_hdr (envi_file, &envi_hdr) != SUCCESS) EXIT_ERROR("Writing the ENVI header file.", "main"); } /* Write the ENVI header for thermal files */ for (ib = 0; ib < output_th->nband; ib++) { /* Create the ENVI header file this band */ if (create_envi_struct (&output_th->metadata.band[ib], &xml_metadata.global, &envi_hdr) != SUCCESS) EXIT_ERROR("Creating the ENVI header structure for this file.", "main"); /* Write the ENVI header */ strcpy (envi_file, output_th->metadata.band[ib].file_name); cptr = strchr (envi_file, '.'); strcpy (cptr, ".hdr"); if (write_envi_hdr (envi_file, &envi_hdr) != SUCCESS) EXIT_ERROR("Writing the ENVI header file.", "main"); } /* Append the reflective and thermal bands to the XML file */ if (append_metadata (output->nband, output->metadata.band, param->input_xml_file_name) != SUCCESS) EXIT_ERROR("appending reflectance and QA bands", "main"); if (input->nband_th > 0) { if (append_metadata (output_th->nband, output_th->metadata.band, param->input_xml_file_name) != SUCCESS) EXIT_ERROR("appending thermal and QA bands", "main"); } /* Free the metadata structure */ free_metadata (&xml_metadata); /* Free memory */ if (!FreeParam(param)) EXIT_ERROR("freeing parameter stucture", "main"); if (!FreeInput(input)) EXIT_ERROR("freeing input file stucture", "main"); if (!FreeLut(lut)) EXIT_ERROR("freeing lut file stucture", "main"); if (!FreeOutput(output)) EXIT_ERROR("freeing output file stucture", "main"); free(line_out); line_out = NULL; free(line_in); line_in = NULL; free(line_out_qa); line_out_qa = NULL; free(line_out_th); line_out_th = NULL; if (zoomx != 1) { free(line_in_thz); free(line_out_thz); } line_in_thz = NULL; line_out_thz = NULL; /* All done */ printf ("lndcal complete.\n"); return (EXIT_SUCCESS); }
/* Change all references to global in the EventInfo struct */ static void saveEventInfoRefs(JNIEnv *env, EventInfo *evinfo) { jthread *pthread; jclass *pclazz; jobject *pobject; jthread thread; jclass clazz; jobject object; char sig; JNI_FUNC_PTR(env,ExceptionClear)(env); if ( evinfo->thread != NULL ) { pthread = &(evinfo->thread); thread = *pthread; *pthread = NULL; saveGlobalRef(env, thread, pthread); } if ( evinfo->clazz != NULL ) { pclazz = &(evinfo->clazz); clazz = *pclazz; *pclazz = NULL; saveGlobalRef(env, clazz, pclazz); } if ( evinfo->object != NULL ) { pobject = &(evinfo->object); object = *pobject; *pobject = NULL; saveGlobalRef(env, object, pobject); } switch (evinfo->ei) { case EI_FIELD_MODIFICATION: if ( evinfo->u.field_modification.field_clazz != NULL ) { pclazz = &(evinfo->u.field_modification.field_clazz); clazz = *pclazz; *pclazz = NULL; saveGlobalRef(env, clazz, pclazz); } sig = evinfo->u.field_modification.signature_type; if ((sig == JDWP_TAG(ARRAY)) || (sig == JDWP_TAG(OBJECT))) { if ( evinfo->u.field_modification.new_value.l != NULL ) { pobject = &(evinfo->u.field_modification.new_value.l); object = *pobject; *pobject = NULL; saveGlobalRef(env, object, pobject); } } break; case EI_FIELD_ACCESS: if ( evinfo->u.field_access.field_clazz != NULL ) { pclazz = &(evinfo->u.field_access.field_clazz); clazz = *pclazz; *pclazz = NULL; saveGlobalRef(env, clazz, pclazz); } break; case EI_EXCEPTION: if ( evinfo->u.exception.catch_clazz != NULL ) { pclazz = &(evinfo->u.exception.catch_clazz); clazz = *pclazz; *pclazz = NULL; saveGlobalRef(env, clazz, pclazz); } break; default: break; } if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) { EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,"ExceptionOccurred"); } }
static void parse_certificates(const options_t *options, pe_ctx_t *ctx) { const IMAGE_DATA_DIRECTORY * const directory = pe_directory_by_entry(ctx, IMAGE_DIRECTORY_ENTRY_SECURITY); if (directory == NULL) return; if (directory->VirtualAddress == 0 || directory->Size == 0) return; uint32_t fileOffset = directory->VirtualAddress; // This a file pointer rather than a common RVA. // TODO(jweyrich): We should count how many certificates the file has, and based on this // decide whether to proceed and open the certificates scope. output_open_scope("certificates", OUTPUT_SCOPE_TYPE_ARRAY); while (fileOffset - directory->VirtualAddress < directory->Size) { // Read the size of this WIN_CERTIFICATE uint32_t *dwLength_ptr = LIBPE_PTR_ADD(ctx->map_addr, fileOffset); if (!pe_can_read(ctx, dwLength_ptr, sizeof(uint32_t))) { output_close_scope(); // certificates // TODO: Should we report something? return; } // Type punning uint32_t dwLength = *(uint32_t *)dwLength_ptr; WIN_CERTIFICATE *cert = LIBPE_PTR_ADD(ctx->map_addr, fileOffset); if (!pe_can_read(ctx, cert, dwLength)) { output_close_scope(); // certificates // TODO: Should we report something? return; } output_open_scope("certificate", OUTPUT_SCOPE_TYPE_OBJECT); static char value[MAX_MSG]; snprintf(value, MAX_MSG, "%u bytes", cert->dwLength); output("Length", value); snprintf(value, MAX_MSG, "0x%x (%s)", cert->wRevision, cert->wRevision == WIN_CERT_REVISION_1_0 ? "1" : cert->wRevision == WIN_CERT_REVISION_2_0 ? "2" : "unknown"); output("Revision", value); snprintf(value, MAX_MSG, "0x%x", cert->wCertificateType); switch (cert->wCertificateType) { default: bsd_strlcat(value, " (UNKNOWN)", MAX_MSG); break; case WIN_CERT_TYPE_X509: bsd_strlcat(value, " (X509)", MAX_MSG); break; case WIN_CERT_TYPE_PKCS_SIGNED_DATA: bsd_strlcat(value, " (PKCS_SIGNED_DATA)", MAX_MSG); break; case WIN_CERT_TYPE_TS_STACK_SIGNED: bsd_strlcat(value, " (TS_STACK_SIGNED)", MAX_MSG); break; } output("Type", value); fileOffset += utils_round_up(cert->dwLength, 8); // Offset to the next certificate. if (fileOffset - directory->VirtualAddress > directory->Size) EXIT_ERROR("either the attribute certificate table or the Size field is corrupted"); switch (cert->wRevision) { default: EXIT_ERROR("unknown wRevision"); case WIN_CERT_REVISION_1_0: EXIT_ERROR("WIN_CERT_REVISION_1_0 is not supported"); case WIN_CERT_REVISION_2_0: break; } switch (cert->wCertificateType) { default: EXIT_ERROR("unknown wCertificateType"); case WIN_CERT_TYPE_X509: EXIT_ERROR("WIN_CERT_TYPE_X509 is not supported"); case WIN_CERT_TYPE_PKCS_SIGNED_DATA: { CRYPT_DATA_BLOB p7data; p7data.cbData = cert->dwLength - offsetof(WIN_CERTIFICATE, bCertificate); p7data.pbData = cert->bCertificate; parse_pkcs7_data(options, &p7data); break; } case WIN_CERT_TYPE_TS_STACK_SIGNED: EXIT_ERROR("WIN_CERT_TYPE_TS_STACK_SIGNED is not supported"); case WIN_CERT_TYPE_EFI_PKCS115: EXIT_ERROR("WIN_CERT_TYPE_EFI_PKCS115 is not supported"); case WIN_CERT_TYPE_EFI_GUID: EXIT_ERROR("WIN_CERT_TYPE_EFI_GUID is not supported"); } output_close_scope(); // certificate } output_close_scope(); // certificates }
int main(int argc, char *argv[]) { pev_config_t config; PEV_INITIALIZE(&config); if (argc < 2) { usage(); exit(EXIT_FAILURE); } output_set_cmdline(argc, argv); options_t *options = parse_options(argc, argv); // opcoes const char *path = argv[argc-1]; pe_ctx_t ctx; pe_err_e err = pe_load_file(&ctx, path); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } err = pe_parse(&ctx); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } if (!pe_is_pe(&ctx)) EXIT_ERROR("not a valid PE file"); IMAGE_OPTIONAL_HEADER *optional = pe_optional(&ctx); if (optional == NULL) return EXIT_FAILURE; uint16_t dllchar = 0; switch (optional->type) { default: return EXIT_FAILURE; case MAGIC_PE32: dllchar = optional->_32->DllCharacteristics; break; case MAGIC_PE64: dllchar = optional->_64->DllCharacteristics; break; } output_open_document(); char field[MAX_MSG]; // aslr snprintf(field, MAX_MSG, "ASLR"); output(field, (dllchar & 0x40) ? "yes" : "no"); // dep/nx snprintf(field, MAX_MSG, "DEP/NX"); output(field, (dllchar & 0x100) ? "yes" : "no"); // seh snprintf(field, MAX_MSG, "SEH"); output(field, (dllchar & 0x400) ? "no" : "yes"); // stack cookies snprintf(field, MAX_MSG, "Stack cookies (EXPERIMENTAL)"); output(field, stack_cookies(&ctx) ? "yes" : "no"); // certificados parse_certificates(options, &ctx); output_close_document(); // libera a memoria free_options(options); // free err = pe_unload(&ctx); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } PEV_FINALIZE(&config); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { PE_FILE pe; FILE *fp = NULL; if (argc < 2) { usage(); exit(1); } parse_options(argc, argv); // opcoes if ((fp = fopen(argv[argc-1], "rb")) == NULL) EXIT_ERROR("file not found or unreadable"); pe_init(&pe, fp); // inicializa o struct pe if (!is_pe(&pe)) EXIT_ERROR("not a valid PE file"); // dos header if (config.dos || config.all_headers || config.all) { IMAGE_DOS_HEADER dos; if (pe_get_dos(&pe, &dos)) print_dos_header(&dos); else { EXIT_ERROR("unable to read DOS header"); } } // coff/file header if (config.coff || config.all_headers || config.all) { IMAGE_COFF_HEADER coff; if (pe_get_coff(&pe, &coff)) print_coff_header(&coff); else { EXIT_ERROR("unable to read COFF file header"); } } // optional header if (config.opt || config.all_headers || config.all) { if (pe_get_optional(&pe)) print_optional_header(&pe); else { EXIT_ERROR("unable to read Optional (Image) file header"); } } // directories if (config.dirs || config.all) { if (pe_get_directories(&pe)) print_directories(&pe); else { EXIT_ERROR("unable to read the Directories entry from Optional header"); } } // imports if (config.imports || config.all) { if (pe_get_directories(&pe)) print_imports(&pe); else { EXIT_ERROR("unable to read the Directories entry from Optional header"); } } // exports if (config.exports || config.all) { if (pe_get_directories(&pe)) print_exports(&pe); else { EXIT_ERROR("unable to read directories from optional header"); } } // sections if (config.all_sections || config.all) { if (pe_get_sections(&pe)) print_sections(&pe); else { EXIT_ERROR("unable to read sections"); } } // free pe_deinit(&pe); return 0; }
static int parse_pkcs7_data(const options_t *options, const CRYPT_DATA_BLOB *blob) { int result = 0; const cert_format_e input_fmt = CERT_FORMAT_DER; PKCS7 *p7 = NULL; BIO *in = NULL; CRYPTO_malloc_init(); ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); in = BIO_new_mem_buf(blob->pbData, blob->cbData); if (in == NULL) { result = -2; goto error; } switch (input_fmt) { default: EXIT_ERROR("unhandled input format for certificate"); case CERT_FORMAT_DER: p7 = d2i_PKCS7_bio(in, NULL); break; case CERT_FORMAT_PEM: p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); break; } if (p7 == NULL) { ERR_print_errors_fp(stderr); result = -3; goto error; } STACK_OF(X509) *certs = NULL; int type = OBJ_obj2nid(p7->type); switch (type) { default: break; case NID_pkcs7_signed: // PKCS7_type_is_signed(p7) certs = p7->d.sign->cert; break; case NID_pkcs7_signedAndEnveloped: // PKCS7_type_is_signedAndEnveloped(p7) certs = p7->d.signed_and_enveloped->cert; break; } const int numcerts = certs != NULL ? sk_X509_num(certs) : 0; for (int i = 0; i < numcerts; i++) { X509 *cert = sk_X509_value(certs, i); print_certificate(options->certout, options->certoutform, cert); // NOTE: Calling X509_free(cert) is unnecessary. } // Print whether certificate signature is valid if (numcerts > 0) { X509 *subject = sk_X509_value(certs, 0); X509 *issuer = sk_X509_value(certs, numcerts - 1); int valid_sig = X509_verify(subject, X509_get_pubkey(issuer)); output("Signature", valid_sig == 1 ? "valid" : "invalid"); } // Print signers if (numcerts > 0) { output_open_scope("signers", OUTPUT_SCOPE_TYPE_ARRAY); for (int i = 0; i < numcerts; i++) { X509 *cert = sk_X509_value(certs, i); X509_NAME *name = X509_get_subject_name(cert); int issuer_name_len = X509_NAME_get_text_by_NID(name, NID_commonName, NULL, 0); if (issuer_name_len > 0) { output_open_scope("signer", OUTPUT_SCOPE_TYPE_OBJECT); char issuer_name[issuer_name_len + 1]; X509_NAME_get_text_by_NID(name, NID_commonName, issuer_name, issuer_name_len + 1); output("Issuer", issuer_name); output_close_scope(); // signer } } output_close_scope(); // signers } error: if (p7 != NULL) PKCS7_free(p7); if (in != NULL) BIO_free(in); // Deallocate everything from OpenSSL_add_all_algorithms EVP_cleanup(); // Deallocate everything from ERR_load_crypto_strings ERR_free_strings(); return result; }
int main(int argc, char **argv, char **envp) { FILE *log; char *line, // where we place the readed line *start, // where our args start *root, // directory to chroot *blkdev, // block device to mount on newroot **new_argv; // init args int i,mounted_twice; // general purpose integer line = blkdev = root = NULL; new_argv = NULL; i=mounted_twice=0; #define EXIT_SILENT fclose(log); \ fatal(argv,envp); \ exit(EXIT_FAILURE); #define EXIT_ERROR(err) fprintf(log, err " - %s\n", strerror(errno)); \ EXIT_SILENT if((log = fopen(LOG,"w")) == NULL) { fatal(argv,envp); exit(EXIT_FAILURE); } // mount /proc if(mount("proc", "/proc", "proc", MS_RELATIME, "")) { EXIT_ERROR("unable to mount /proc"); } // alloc line if((line = malloc(COMMAND_LINE_SIZE*sizeof(char))) == NULL) { umount("/proc"); EXIT_ERROR("malloc"); } // read cmdline if(read_our_cmdline(line)) { umount("/proc"); free(line); EXIT_ERROR("unable to read /proc/cmdline"); } umount("/proc"); if (!(start=strstr(line,CMDLINE_OPTION))) { fprintf(log,"unable to find \"%s\" in \"%s\"\n",CMDLINE_OPTION,line); free(line); EXIT_SILENT; } start+=CMDLINE_OPTION_LEN; if(parser(start,&blkdev,&root,&new_argv)) { free(line); EXIT_ERROR("parsing failed"); } free(line); if(mount("sysfs","/sys","sysfs",MS_RELATIME,"")) { EXIT_ERROR("unable to mount /sys"); } mdev(envp); // make sure this was made for(i=1;access(blkdev, R_OK) && i < TIMEOUT;i++) { sleep(1); mdev(envp); } umount("/sys"); //mount blkdev on NEWROOT if(mount(blkdev,NEWROOT,"ext4",0,"")) { fprintf(log,"unable to mount \"%s\" on %s - %s\n",blkdev,NEWROOT,strerror(errno)); free(blkdev); free(root); for(i=0;new_argv[i];i++) free(new_argv[i]); EXIT_SILENT; } free(blkdev); blkdev = root; // keep a track of the old pointer //if root is an ext image mount it on NEWROOT //if root is an initrd(.gz)? file extract it into NEWROOT if(!try_loop_mount(&root,NEWROOT) && !try_initrd_mount(&root,NEWROOT)) { if(blkdev != root) // NEWROOT has been mounted again mounted_twice=1; //check for init existence i=strlen(root) + strlen(new_argv[0]); if((line=malloc((i+1)*sizeof(char)))) { strncpy(line,root,i); strncat(line,new_argv[0],i); line[i]='\0'; if(!access(line,R_OK|X_OK)) { if(!chdir(root) && !chroot(root)) { free(root); fclose(log); execve(new_argv[0],new_argv,envp); } else { fprintf(log,"cannot chroot/chdir to \"%s\" - %s\n",root,strerror(errno)); free(root); for(i=0;new_argv[i];i++) free(new_argv[i]); fclose(log); umount(NEWROOT); if(mounted_twice) umount(NEWROOT); } } else { fprintf(log,"cannot execute \"%s\" - %s\n",line,strerror(errno)); free(line); free(root); for(i=0;new_argv[i];i++) free(new_argv[i]); fclose(log); umount(NEWROOT); if(mounted_twice) umount(NEWROOT); } } else { fprintf(log,"malloc - %s\n",strerror(errno)); free(root); for(i=0;new_argv[i];i++) free(new_argv[i]); fclose(log); umount(NEWROOT); if(mounted_twice) umount(NEWROOT); } } else { if(root) // try_loop_mount reallocate root, a malloc problem can be happend { if(blkdev!=root) umount(NEWROOT); fprintf(log,"try_(loop/initrd)_mount \"%s\" on %s - %s\n",root,NEWROOT,strerror(errno)); free(root); } else fprintf(log,"try_loop_mount NULL root - %s\n",strerror(errno)); for(i=0;new_argv[i];i++) free(new_argv[i]); fclose(log); umount(NEWROOT); } fatal(argv,envp); exit(EXIT_FAILURE); }
static void print_imports(PE_FILE *pe) { QWORD va; // store temporary addresses long aux; IMAGE_IMPORT_DESCRIPTOR id; char c = 0; char dllname[MAX_DLL_NAME]; unsigned int i; va = pe->directories_ptr[IMAGE_DIRECTORY_ENTRY_IMPORT] ? pe->directories_ptr[IMAGE_DIRECTORY_ENTRY_IMPORT]->VirtualAddress : 0; if (!va) EXIT_ERROR("import directory not found"); if (fseek(pe->handle, rva2ofs(pe, va), SEEK_SET)) EXIT_ERROR("error seeking file"); memset(&id, 0, sizeof(id)); memset(&dllname, 0, sizeof(dllname)); output("Imported functions", NULL); while (1) { if (!fread(&id, sizeof(id), 1, pe->handle)) return; if (!id.u1.OriginalFirstThunk) break; aux = ftell(pe->handle); va = rva2ofs(pe, id.Name); if (!va) return; // shortcut to read DLL name if (fseek(pe->handle, va, SEEK_SET)) return; // print dll name for (i=0; i < MAX_DLL_NAME; i++) { fread(&c, sizeof(c), 1, pe->handle); if (!c) break; dllname[i] = c; } output(dllname, NULL); memset(&dllname, 0, sizeof(dllname)); if (fseek(pe->handle, aux, SEEK_SET)) // restore file pointer return; // search for dll imported functions va = rva2ofs(pe, id.u1.OriginalFirstThunk); if (!va) return; print_imported_functions(pe, va); } }
int main(int argc, char **argv) { pev_config_t config; PEV_INITIALIZE(&config); if (argc < 3) { usage(); exit(EXIT_FAILURE); } output_set_cmdline(argc, argv); options_t *options = parse_options(argc, argv); // opcoes const char *path = argv[argc-1]; pe_ctx_t ctx; pe_err_e err = pe_load_file(&ctx, path); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } err = pe_parse(&ctx); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } if (!pe_is_pe(&ctx)) EXIT_ERROR("not a valid PE file"); output_open_document(); NODE_PERES *node = discoveryNodesPeres(&ctx); if (node == NULL) { fprintf(stderr, "this file has no resources\n"); return EXIT_SUCCESS; } if (options->all) { showInformations(node); showStatistics(node); extractResources(&ctx, node); showVersion(&ctx, node); } else { if (options->extract) extractResources(&ctx, node); if (options->info) showInformations(node); if (options->statistics) showStatistics(node); if (options->version) showVersion(&ctx, node); } output_close_document(); freeNodes(node); // libera a memoria free_options(options); // free err = pe_unload(&ctx); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } PEV_FINALIZE(&config); return EXIT_SUCCESS; }
static options_t *parse_options(int argc, char *argv[]) { options_t *options = malloc_s(sizeof(options_t)); memset(options, 0, sizeof(options_t)); /* Parameters for getopt_long() function */ static const char short_options[] = "a:f:isxvV"; static const struct option long_options[] = { { "all", required_argument, NULL, 'a' }, { "format", required_argument, NULL, 'f' }, { "info", no_argument, NULL, 'i' }, { "statistics", no_argument, NULL, 's' }, { "extract", no_argument, NULL, 'x' }, { "file-version", no_argument, NULL, 'v' }, { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 1 }, { NULL, 0, NULL, 0 } }; int c, ind; while ((c = getopt_long(argc, argv, short_options, long_options, &ind))) { if (c < 0) break; switch (c) { case 'a': options->all = true; break; case 'f': if (output_set_format_by_name(optarg) < 0) EXIT_ERROR("invalid format option"); break; case 'i': options->info = true; break; case 's': options->statistics = true; break; case 'x': options->extract = true; break; case 'v': options->version = true; break; case 'V': printf("%s %s\n%s\n", PROGRAM, TOOLKIT, COPY); exit(EXIT_SUCCESS); case 1: // --help option usage(); exit(EXIT_SUCCESS); default: fprintf(stderr, "%s: try '--help' for more information\n", PROGRAM); exit(EXIT_FAILURE); } } return options; }
int main(int argc, char *argv[]) { pev_config_t config; PEV_INITIALIZE(&config); if (argc < 2) { usage(); return EXIT_FAILURE; } output_set_cmdline(argc, argv); OpenSSL_add_all_digests(); options_t *options = parse_options(argc, argv); pe_ctx_t ctx; pe_err_e err = pe_load_file(&ctx, argv[argc-1]); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } err = pe_parse(&ctx); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } if (!pe_is_pe(&ctx)) EXIT_ERROR("not a valid PE file"); const IMAGE_SECTION_HEADER *section_ptr = NULL; const unsigned char *data = NULL; uint64_t data_size = 0; unsigned c = pe_sections_count(&ctx); IMAGE_SECTION_HEADER ** const sections = pe_sections(&ctx); char hash_value[EVP_MAX_MD_SIZE * 2 + 1]; data = ctx.map_addr; data_size = pe_filesize(&ctx); output_open_document(); if (options->all) { output_open_scope("file", OUTPUT_SCOPE_TYPE_OBJECT); output("filepath", ctx.path); print_basic_hash(data, data_size); output_close_scope(); // file } output_open_scope("headers", OUTPUT_SCOPE_TYPE_ARRAY); if (options->all || options->headers.all || options->headers.dos) { const IMAGE_DOS_HEADER *dos_hdr = pe_dos(&ctx); data = (const unsigned char *)dos_hdr; data_size = sizeof(IMAGE_DOS_HEADER); output_open_scope("header", OUTPUT_SCOPE_TYPE_OBJECT); output("header_name", "IMAGE_DOS_HEADER"); PRINT_HASH_OR_HASHES; output_close_scope(); // header } if (options->all || options->headers.all || options->headers.coff) { const IMAGE_COFF_HEADER *coff_hdr = pe_coff(&ctx); data = (const unsigned char *)coff_hdr; data_size = sizeof(IMAGE_COFF_HEADER); output_open_scope("header", OUTPUT_SCOPE_TYPE_OBJECT); output("header_name", "IMAGE_COFF_HEADER"); PRINT_HASH_OR_HASHES; output_close_scope(); // header } if (options->all || options->headers.all || options->headers.optional) { const IMAGE_OPTIONAL_HEADER *opt_hdr = pe_optional(&ctx); switch (opt_hdr->type) { case MAGIC_ROM: // Oh boy! We do not support ROM. Abort! fprintf(stderr, "ROM image is not supported\n"); break; case MAGIC_PE32: if (!pe_can_read(&ctx, opt_hdr->_32, sizeof(IMAGE_OPTIONAL_HEADER_32))) { // TODO: Should we report something? break; } data = (const unsigned char *)opt_hdr->_32; data_size = sizeof(IMAGE_OPTIONAL_HEADER_32); break; case MAGIC_PE64: if (!pe_can_read(&ctx, opt_hdr->_64, sizeof(IMAGE_OPTIONAL_HEADER_64))) { // TODO: Should we report something? break; } data = (const unsigned char *)opt_hdr->_64; data_size = sizeof(IMAGE_OPTIONAL_HEADER_64); break; } output_open_scope("header", OUTPUT_SCOPE_TYPE_OBJECT); output("header_name", "IMAGE_OPTIONAL_HEADER"); PRINT_HASH_OR_HASHES; output_close_scope(); // header } output_close_scope(); // headers if (options->all) { output_open_scope("sections", OUTPUT_SCOPE_TYPE_ARRAY); for (unsigned int i=0; i<c; i++) { data_size = sections[i]->SizeOfRawData; data = LIBPE_PTR_ADD(ctx.map_addr, sections[i]->PointerToRawData); output_open_scope("section", OUTPUT_SCOPE_TYPE_OBJECT); output("section_name", (char *)sections[i]->Name); if (data_size) { PRINT_HASH_OR_HASHES; } output_close_scope(); // section } output_close_scope(); // sections } else if (options->sections.name != NULL) { const IMAGE_SECTION_HEADER *section = pe_section_by_name(&ctx, options->sections.name); if (section == NULL) { EXIT_ERROR("The requested section could not be found on this binary"); } section_ptr = section; } else if (options->sections.index > 0) { const uint16_t num_sections = pe_sections_count(&ctx); if (num_sections == 0 || options->sections.index > num_sections) { EXIT_ERROR("The requested section could not be found on this binary"); } IMAGE_SECTION_HEADER ** const sections = pe_sections(&ctx); const IMAGE_SECTION_HEADER *section = sections[options->sections.index - 1]; section_ptr = section; } if (section_ptr != NULL) { if (section_ptr->SizeOfRawData > 0) { const uint8_t *section_data_ptr = LIBPE_PTR_ADD(ctx.map_addr, section_ptr->PointerToRawData); // printf("map_addr = %p\n", ctx.map_addr); // printf("section_data_ptr = %p\n", section_data_ptr); // printf("SizeOfRawData = %u\n", section_ptr->SizeOfRawData); if (!pe_can_read(&ctx, section_data_ptr, section_ptr->SizeOfRawData)) { EXIT_ERROR("The requested section has an invalid size"); } data = (const unsigned char *)section_data_ptr; data_size = section_ptr->SizeOfRawData; } else { data = (const unsigned char *)""; data_size = 0; } } if (!options->all && data != NULL) { char hash_value[EVP_MAX_MD_SIZE * 2 + 1]; if (options->algorithms.all && options->all) { print_basic_hash(data, data_size); } else if (options->algorithms.alg_name != NULL) { calc_hash(options->algorithms.alg_name, data, data_size, hash_value); output(options->algorithms.alg_name, hash_value); } else { print_basic_hash(data, data_size); } } output_close_document(); // free free_options(options); err = pe_unload(&ctx); if (err != LIBPE_E_OK) { pe_error_print(stderr, err); return EXIT_FAILURE; } EVP_cleanup(); // Clean OpenSSL_add_all_digests. PEV_FINALIZE(&config); return EXIT_SUCCESS; }
static options_t *parse_options(int argc, char *argv[]) { options_t *options = malloc_s(sizeof(options_t)); memset(options, 0, sizeof(options_t)); // parameters for getopt_long() function static const char short_options[] = "f:a:h:s:v"; static const struct option long_options[] = { { "help", no_argument, NULL, 1 }, { "format", required_argument, NULL, 'f' }, { "algorithm", required_argument, NULL, 'a' }, { "header", required_argument, NULL, 'h' }, { "section-name", required_argument, NULL, 's' }, { "section-index", required_argument, NULL, 2 }, { "version", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; // Default options. options->algorithms.all = true; options->headers.all = true; options->all = true; int c, ind; while ((c = getopt_long(argc, argv, short_options, long_options, &ind))) { if (c < 0) break; switch (c) { case 1: // --help option usage(); exit(EXIT_SUCCESS); case 'f': if (output_set_format_by_name(optarg) < 0) EXIT_ERROR("invalid format option"); break; case 'a': options->algorithms.all = false; parse_hash_algorithm(options, optarg); break; case 's': options->all = false; options->headers.all = false; // TODO: How do we need to handle non-ascii names? options->sections.name = strdup(optarg); break; case 2: options->all = false; options->headers.all = false; options->sections.index = strtol(optarg, NULL, 10); if (options->sections.index < 1 || options->sections.index > MAX_SECTIONS) { EXIT_ERROR("Bad argument for section-index,"); } break; case 'v': printf("%s %s\n%s\n", PROGRAM, TOOLKIT, COPY); exit(EXIT_SUCCESS); case 'h': options->all = false; options->headers.all = false; parse_header_name(options, optarg); break; default: fprintf(stderr, "%s: try '--help' for more information\n", PROGRAM); exit(EXIT_FAILURE); } } // TODO: Warn about simultaneous usage of -h, -s, and --section-index. return options; }
/* * Determine if this event is interesting to this handler. * Do so by checking each of the handler's filters. * Return false if any of the filters fail, * true if the handler wants this event. * Anyone modifying this function should check * eventFilterRestricted_passesUnloadFilter and * eventFilter_predictFiltering as well. * * If shouldDelete is returned true, a count filter has expired * and the corresponding node should be deleted. */ jboolean eventFilterRestricted_passesFilter(JNIEnv *env, char *classname, EventInfo *evinfo, HandlerNode *node, jboolean *shouldDelete) { jthread thread; jclass clazz; jmethodID method; Filter *filter = FILTERS_ARRAY(node); int i; *shouldDelete = JNI_FALSE; thread = evinfo->thread; clazz = evinfo->clazz; method = evinfo->method; /* * Suppress most events if they happen in debug threads */ if ((evinfo->ei != EI_CLASS_PREPARE) && (evinfo->ei != EI_GC_FINISH) && (evinfo->ei != EI_CLASS_LOAD) && threadControl_isDebugThread(thread)) { return JNI_FALSE; } for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) { switch (filter->modifier) { case JDWP_REQUEST_MODIFIER(ThreadOnly): if (!isSameObject(env, thread, filter->u.ThreadOnly.thread)) { return JNI_FALSE; } break; case JDWP_REQUEST_MODIFIER(ClassOnly): /* Class filters catch events in the specified * class and any subclass/subinterface. */ if (!JNI_FUNC_PTR(env,IsAssignableFrom)(env, clazz, filter->u.ClassOnly.clazz)) { return JNI_FALSE; } break; /* This is kinda cheating assumming the event * fields will be in the same locations, but it is * true now. */ case JDWP_REQUEST_MODIFIER(LocationOnly): if (evinfo->method != filter->u.LocationOnly.method || evinfo->location != filter->u.LocationOnly.location || !isSameObject(env, clazz, filter->u.LocationOnly.clazz)) { return JNI_FALSE; } break; case JDWP_REQUEST_MODIFIER(FieldOnly): /* Field watchpoints can be triggered from the * declared class or any subclass/subinterface. */ if ((evinfo->u.field_access.field != filter->u.FieldOnly.field) || !isSameObject(env, evinfo->u.field_access.field_clazz, filter->u.FieldOnly.clazz)) { return JNI_FALSE; } break; case JDWP_REQUEST_MODIFIER(ExceptionOnly): /* do we want caught/uncaught exceptions */ if (!((evinfo->u.exception.catch_clazz == NULL)? filter->u.ExceptionOnly.uncaught : filter->u.ExceptionOnly.caught)) { return JNI_FALSE; } /* do we care about exception class */ if (filter->u.ExceptionOnly.exception != NULL) { jclass exception = evinfo->object; /* do we want this exception class */ if (!JNI_FUNC_PTR(env,IsInstanceOf)(env, exception, filter->u.ExceptionOnly.exception)) { return JNI_FALSE; } } break; case JDWP_REQUEST_MODIFIER(InstanceOnly): { jobject eventInst = eventInstance(evinfo); jobject filterInst = filter->u.InstanceOnly.instance; /* if no error and doesn't match, don't pass * filter */ if (eventInst != NULL && !isSameObject(env, eventInst, filterInst)) { return JNI_FALSE; } break; } case JDWP_REQUEST_MODIFIER(Count): { JDI_ASSERT(filter->u.Count.count > 0); if (--filter->u.Count.count > 0) { return JNI_FALSE; } *shouldDelete = JNI_TRUE; break; } case JDWP_REQUEST_MODIFIER(Conditional): /*** if (... filter->u.Conditional.exprID ...) { return JNI_FALSE; } ***/ break; case JDWP_REQUEST_MODIFIER(ClassMatch): { if (!patternStringMatch(classname, filter->u.ClassMatch.classPattern)) { return JNI_FALSE; } break; } case JDWP_REQUEST_MODIFIER(ClassExclude): { if (patternStringMatch(classname, filter->u.ClassExclude.classPattern)) { return JNI_FALSE; } break; } case JDWP_REQUEST_MODIFIER(Step): if (!isSameObject(env, thread, filter->u.Step.thread)) { return JNI_FALSE; } if (!stepControl_handleStep(env, thread, clazz, method)) { return JNI_FALSE; } break; case JDWP_REQUEST_MODIFIER(SourceNameMatch): { char* desiredNamePattern = filter->u.SourceNameOnly.sourceNamePattern; if (!searchAllSourceNames(env, clazz, desiredNamePattern) == 1) { /* The name isn't in the SDE; try the sourceName in the ref * type */ char *sourceName = 0; jvmtiError error = JVMTI_FUNC_PTR(gdata->jvmti,GetSourceFileName) (gdata->jvmti, clazz, &sourceName); if (error == JVMTI_ERROR_NONE && sourceName != 0 && patternStringMatch(sourceName, desiredNamePattern)) { // got a hit - report the event jvmtiDeallocate(sourceName); break; } // We have no match, we have no source file name, // or we got a JVM TI error. Don't report the event. jvmtiDeallocate(sourceName); return JNI_FALSE; } break; } default: EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"Invalid filter modifier"); return JNI_FALSE; } } return JNI_TRUE; }