/* * Get a TLV as a string */ DWORD packet_get_tlv_string(Packet *packet, TlvType type, Tlv *tlv) { DWORD res; if ((res = packet_get_tlv(packet, type, tlv)) == ERROR_SUCCESS) res = packet_is_tlv_null_terminated(packet, tlv); return res; }
/* * Validate command arguments */ DWORD command_validate_arguments(Command *command, Packet *packet) { PacketDispatcher *dispatcher = NULL; PacketTlvType type = packet_get_type(packet); DWORD res = ERROR_SUCCESS, packetIndex, commandIndex; Tlv current; // Select the dispatcher table if ((type == PACKET_TLV_TYPE_RESPONSE) || (type == PACKET_TLV_TYPE_PLAIN_RESPONSE)) dispatcher = &command->response; else dispatcher = &command->request; // Enumerate the arguments, validating the meta types of each for (commandIndex = 0, packetIndex = 0; ((packet_enum_tlv(packet, packetIndex, TLV_TYPE_ANY, ¤t) == ERROR_SUCCESS) && (res == ERROR_SUCCESS)); commandIndex++, packetIndex++) { TlvMetaType tlvMetaType; // Check to see if we've reached the end of the command arguments if ((dispatcher->numArgumentTypes) && (commandIndex == (dispatcher->numArgumentTypes & ARGUMENT_FLAG_MASK))) { // If the repeat flag is set, reset the index if (commandIndex & ARGUMENT_FLAG_REPEAT) commandIndex = 0; else break; } // Make sure the argument is at least one of the meta types tlvMetaType = packet_get_tlv_meta(packet, ¤t); // Validate argument meta types switch (tlvMetaType) { case TLV_META_TYPE_STRING: if (packet_is_tlv_null_terminated(packet, ¤t) != ERROR_SUCCESS) res = ERROR_INVALID_PARAMETER; break; default: break; } if ((res != ERROR_SUCCESS) && (commandIndex < dispatcher->numArgumentTypes)) break; } return res; }
/* * Set the register state of the supplied thread * * req: TLV_TYPE_THREAD_HANDLE - The thread to set * req: TLV_TYPE_REGISTER x N - The registers to set */ DWORD request_sys_process_thread_set_regs(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); HANDLE thread; DWORD result = ERROR_SUCCESS; do { if ((thread = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_THREAD_HANDLE))) { CONTEXT context; DWORD index = 0; Tlv reg; memset(&context, 0, sizeof(context)); // Get the current thread register state context.ContextFlags = CONTEXT_FULL; if (!GetThreadContext(thread, &context)) { result = GetLastError(); break; } // Enumerate through all of the register we're setting while (packet_enum_tlv(packet, index++, TLV_TYPE_REGISTER, ®) == ERROR_SUCCESS) { LPCSTR name; ULONG value; Tlv nameTlv, valueTlv; // Get the group's entries if ((packet_get_tlv_group_entry(packet, ®, TLV_TYPE_REGISTER_NAME, &nameTlv) != ERROR_SUCCESS) || (packet_get_tlv_group_entry(packet, ®, TLV_TYPE_REGISTER_VALUE_32, &valueTlv) != ERROR_SUCCESS)) continue; // Validate them if ((packet_is_tlv_null_terminated(packet, &nameTlv) != ERROR_SUCCESS) || (valueTlv.header.length < sizeof(ULONG))) continue; // Stash them name = (LPCSTR)nameTlv.buffer; value = ntohl(*(PULONG)valueTlv.buffer); // Set this register's value set_thread_register_value(&context, name, value); } // Update the thread's context if (!SetThreadContext(thread, &context)) { result = GetLastError(); break; } } else result = ERROR_INVALID_PARAMETER; } while (0); packet_transmit_response(result, remote, response); return ERROR_SUCCESS; }