/// <summary> /// This generates the argument string based on the calling convention of this /// function. It truncates the arguments at around the specified pixel width of the column. /// </summary> /// <param name="callRecording"></param> /// <param name="columnWidth"></param> /// <returns></returns> public ARGUMENT_STRING_COLLECTION getArgumentString(oSingleData callRecording, int columnWidth, Font font) { // Get the argument string collection ARGUMENT_STRING_COLLECTION arguments = getArgumentString(callRecording); // Truncate the string values to approximately the right size for (int i = 0; i < arguments.values.Count; i++) { // Test the indexTooLong value string value = arguments.values[i]; string name = arguments.names[i]; Size size = TextRenderer.MeasureText(name + "=" + value, font); if (size.Width > columnWidth - 2 && value.Length > 5) { // Too long of a string int indexTooLong = value.Length; int indexTooShort = 0; // Make our next guess, that will reduce the set in half int guess = (indexTooLong - indexTooShort) / 2 + indexTooShort; // Rounding down is nice. while (guess != indexTooShort) { // Test this guess length if (TextRenderer.MeasureText(name + "=" + value.Substring(0, guess) + "...", font).Width > columnWidth - 2) { indexTooLong = guess; } else { indexTooShort = guess; } // Make the next guess guess = (indexTooLong - indexTooShort) / 2 + indexTooShort; } // We found the prefect length that is just shorter than the column width with the "..." arguments.values[i] = value.Substring(0, guess) + "..."; } } return(arguments); }
/// <summary> /// This generates the argument string based on the calling convention of this /// function. /// </summary> /// <param name="callRecording"></param> public ARGUMENT_STRING_COLLECTION getArgumentString(oSingleData callRecording) { ARGUMENT_STRING_COLLECTION result = new ARGUMENT_STRING_COLLECTION(); result.names = new List <string>((int)numParams + 3); result.values = new List <string>((int)numParams + 3); if (arguments.Count < 3) // Must have all three registers at least. { return(result); } int dereferenceIndex = callRecording.dereferences.Count() - 1; string deref; // ECX, __fastcall argument 1, __thiscall 'this' pointer if (dereferenceIndex >= 0 && callRecording.dereferences[dereferenceIndex].argumentIndex == 0) { // ECX with dereference result.values.Add(arguments[0].getValueString(callRecording.ecx, callRecording.dereferences[dereferenceIndex])); result.names.Add(arguments[0].getName()); dereferenceIndex--; } else { // ECX no dereference result.values.Add(arguments[0].getValueString(callRecording.ecx)); result.names.Add(arguments[0].getName()); } // EDX, __fastcall argument 2 if (dereferenceIndex >= 0 && callRecording.dereferences[dereferenceIndex].argumentIndex == 1) { // EDX with dereference result.values.Add(arguments[1].getValueString(callRecording.edx, callRecording.dereferences[dereferenceIndex])); result.names.Add(arguments[1].getName()); dereferenceIndex--; } else { // EDX no dereference result.values.Add(arguments[1].getValueString(callRecording.edx)); result.names.Add(arguments[1].getName()); } // EAX, __fastcall argument 3 on borland if (dereferenceIndex >= 0 && callRecording.dereferences[dereferenceIndex].argumentIndex == 2) { // EAX with dereference result.values.Add(arguments[2].getValueString(callRecording.eax, callRecording.dereferences[dereferenceIndex])); result.names.Add(arguments[2].getName()); dereferenceIndex--; } else { // EAX no dereference result.values.Add(arguments[2].getValueString(callRecording.eax)); result.names.Add(arguments[2].getName()); } // STACK ARGUMENTS // Create room for the variables for (int i = 0; i < callRecording.arguments.Count(); i++) { result.values.Add(""); result.names.Add(""); } // Load the data into the variables for (int i = callRecording.arguments.Count() - 1; i >= 0; i--) { if (dereferenceIndex >= 0 && callRecording.dereferences[dereferenceIndex].argumentIndex == i + 4) { // Stack argument with dereference result.values[i + 3] = (arguments[i + 3].getValueString(callRecording.arguments[i], callRecording.dereferences[dereferenceIndex])); result.names[i + 3] = arguments[i + 3].getName(); dereferenceIndex--; } else { // Stack argument no dereference result.values[i + 3] = arguments[i + 3].getValueString(callRecording.arguments[i]); result.names[i + 3] = arguments[i + 3].getName(); } } return(result); }