hardsploit_gui 2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +22 -0
- data/Rakefile +1 -0
- data/bin/hardsploit_gui +3 -0
- data/lib/Firmware/FPGA/I2C/I2C_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_I2C_INTERACT.rpd +0 -0
- data/lib/Firmware/FPGA/PARALLEL/NO_MUX_PARALLEL_MEMORY/HARDSPLOIT_FIRMWARE_FPGA_NO_MUX_PARALLEL_MEMORY.rpd +0 -0
- data/lib/Firmware/FPGA/SPI/SPI_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_SPI_INTERACT.rpd +0 -0
- data/lib/Firmware/FPGA/SWD/SWD_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_SWD_INTERACT.rpd +0 -0
- data/lib/Firmware/FPGA/TEST/TEST_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_TEST_INTERACT.rpd +0 -0
- data/lib/Firmware/FPGA/VersionFPGA.rb +5 -0
- data/lib/Firmware/UC/HARDSPLOIT_FIRMWARE_UC.bin +0 -0
- data/lib/Firmware/UC/VersionUC.rb +12 -0
- data/lib/HardsploitAPI/HardsploitAPI.rb +134 -0
- data/lib/HardsploitAPI/HardsploitAPI_CONSTANT.rb +145 -0
- data/lib/HardsploitAPI/HardsploitAPI_FIRMWARE.rb +311 -0
- data/lib/HardsploitAPI/HardsploitAPI_I2C.rb +218 -0
- data/lib/HardsploitAPI/HardsploitAPI_NO_MUX_PARALLELE_MEMORY.rb +229 -0
- data/lib/HardsploitAPI/HardsploitAPI_SPI.rb +179 -0
- data/lib/HardsploitAPI/HardsploitAPI_TEST_INTERACT.rb +98 -0
- data/lib/HardsploitAPI/HardsploitAPI_USB_COMMUNICATION.rb +149 -0
- data/lib/HardsploitAPI/LICENSE.txt +674 -0
- data/lib/HardsploitAPI/README.md +22 -0
- data/lib/HardsploitAPI/SWD/HardsploitAPI_SWD.rb +249 -0
- data/lib/HardsploitAPI/SWD/HardsploitAPI_SWD_DEBUG.rb +102 -0
- data/lib/HardsploitAPI/SWD/HardsploitAPI_SWD_MEM_AP.rb +78 -0
- data/lib/HardsploitAPI/SWD/HardsploitAPI_SWD_STM32.rb +104 -0
- data/lib/HardsploitAPI/TRADEMARK +3 -0
- data/lib/LICENSE.txt +674 -0
- data/lib/README.md +22 -0
- data/lib/TRADEMARK +3 -0
- data/lib/class/Chip_editor.rb +448 -0
- data/lib/class/Command_editor.rb +268 -0
- data/lib/class/Command_table.rb +239 -0
- data/lib/class/Console.rb +28 -0
- data/lib/class/Export_manager.rb +124 -0
- data/lib/class/Firmware.rb +29 -0
- data/lib/class/Generic_commands.rb +275 -0
- data/lib/class/HardsploitGUI.rb +462 -0
- data/lib/class/I2C/I2c_command.rb +48 -0
- data/lib/class/I2C/I2c_export.rb +121 -0
- data/lib/class/I2C/I2c_import.rb +92 -0
- data/lib/class/I2C/I2c_settings.rb +117 -0
- data/lib/class/PARALLEL/Parallel_export.rb +146 -0
- data/lib/class/PARALLEL/Parallel_import.rb +88 -0
- data/lib/class/PARALLEL/Parallel_settings.rb +102 -0
- data/lib/class/SPI/Spi_export.rb +141 -0
- data/lib/class/SPI/Spi_import.rb +112 -0
- data/lib/class/SPI/Spi_settings.rb +90 -0
- data/lib/class/Wire_helper.rb +246 -0
- data/lib/db/associations.rb +125 -0
- data/lib/db/hs.db +0 -0
- data/lib/gui/gui_chip_editor.rb +355 -0
- data/lib/gui/gui_chip_management.rb +372 -0
- data/lib/gui/gui_command_editor.rb +218 -0
- data/lib/gui/gui_export_manager.rb +93 -0
- data/lib/gui/gui_generic_commands.rb +164 -0
- data/lib/gui/gui_generic_export.rb +148 -0
- data/lib/gui/gui_generic_import.rb +126 -0
- data/lib/gui/gui_i2c_command.rb +115 -0
- data/lib/gui/gui_i2c_settings.rb +201 -0
- data/lib/gui/gui_parallel_settings.rb +194 -0
- data/lib/gui/gui_spi_import.rb +126 -0
- data/lib/gui/gui_spi_settings.rb +187 -0
- data/lib/gui/gui_wire_helper.rb +99 -0
- data/lib/gui_designer/gui_chip_editor.ui +553 -0
- data/lib/gui_designer/gui_chip_management.ui +842 -0
- data/lib/gui_designer/gui_command_editor.ui +347 -0
- data/lib/gui_designer/gui_export_manager.ui +115 -0
- data/lib/gui_designer/gui_generic_commands.ui +258 -0
- data/lib/gui_designer/gui_generic_export.ui +179 -0
- data/lib/gui_designer/gui_generic_import.ui +142 -0
- data/lib/gui_designer/gui_i2c_command.ui +145 -0
- data/lib/gui_designer/gui_i2c_settings.ui +261 -0
- data/lib/gui_designer/gui_parallel_settings.ui +244 -0
- data/lib/gui_designer/gui_processing.ui +81 -0
- data/lib/gui_designer/gui_spi_settings.ui +321 -0
- data/lib/gui_designer/gui_wire_helper.ui +117 -0
- data/lib/hardsploit.rb +122 -0
- data/lib/images/search.png +0 -0
- data/lib/logs/error.log +0 -0
- metadata +236 -0
@@ -0,0 +1,218 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#===================================================
|
3
|
+
# Hardsploit API - By Opale Security
|
4
|
+
# www.opale-security.com || www.hardsploit.io
|
5
|
+
# License: GNU General Public License v3
|
6
|
+
# License URI: http://www.gnu.org/licenses/gpl.txt
|
7
|
+
#===================================================
|
8
|
+
|
9
|
+
class HardsploitAPI
|
10
|
+
public
|
11
|
+
# Interact with I2C bus
|
12
|
+
# * +speed+:: I2C::KHZ_100 , I2C::KHZ_400 , I2C::KHZ_1000
|
13
|
+
# * +payload+:: payload to send
|
14
|
+
def i2c_Interact(*args)
|
15
|
+
parametters = HardsploitAPI.checkParametters(["speed","payload"],args)
|
16
|
+
speed = parametters[:speed]
|
17
|
+
payload = parametters[:payload]
|
18
|
+
|
19
|
+
if (speed < 0) and (speed >3) then
|
20
|
+
raise TypeError, 'Speed must be between 0 and 3'
|
21
|
+
end
|
22
|
+
|
23
|
+
if (payload.size > 4000) then
|
24
|
+
raise TypeError, 'Size of the data need to be less than 4000'
|
25
|
+
end
|
26
|
+
|
27
|
+
packet = Array.new
|
28
|
+
packet.push 0 #low byte of lenght of trame refresh automaticly before send by usb
|
29
|
+
packet.push 0 #high byte of lenght of trame refresh automaticly before send by usb
|
30
|
+
packet.push HardsploitAPI.lowByte(USB_COMMAND::FPGA_COMMAND)
|
31
|
+
packet.push HardsploitAPI.highByte(USB_COMMAND::FPGA_COMMAND)
|
32
|
+
|
33
|
+
packet.push 0x50 #Command RAW COMMUNICATION TO FPGA FIFO
|
34
|
+
|
35
|
+
packet.push speed #Add speed
|
36
|
+
packet.concat payload #Add data
|
37
|
+
|
38
|
+
sendPacket packet
|
39
|
+
|
40
|
+
tmp= receiveDATA(2000)
|
41
|
+
case tmp
|
42
|
+
when HardsploitAPI::USB_STATE::BUSY
|
43
|
+
return USB_STATE::BUSY
|
44
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
45
|
+
return USB_STATE::TIMEOUT_RECEIVE
|
46
|
+
else
|
47
|
+
#remove header (4 bytes 2 for size 2 for type of command)
|
48
|
+
return tmp.bytes.drop(4)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Start I2C scan to find addresses
|
53
|
+
# * +speed+:: I2C::KHZ_100 , I2C::KHZ_400 , I2C::KHZ_1000
|
54
|
+
# * Return An array 256 value for each addresse if 0 not present if 1 present
|
55
|
+
def i2c_Scan(*args)
|
56
|
+
parametters = HardsploitAPI.checkParametters(["speed"],args)
|
57
|
+
speed = parametters[:speed]
|
58
|
+
|
59
|
+
if (speed < 0) and (speed >3) then
|
60
|
+
raise TypeError, 'Speed must be between 0 and 3'
|
61
|
+
end
|
62
|
+
|
63
|
+
array_i2c_scan = Array.new
|
64
|
+
result_scan = Array.new
|
65
|
+
return_scan = Array.new
|
66
|
+
|
67
|
+
#we want scan just read address it is a partial scan (fastest)
|
68
|
+
for i in (1..255).step(2) do
|
69
|
+
array_i2c_scan.push HardsploitAPI.lowByte(1) #Count Low Byte
|
70
|
+
array_i2c_scan.push HardsploitAPI.highByte(1) #Count High Byte
|
71
|
+
array_i2c_scan.push i
|
72
|
+
end
|
73
|
+
|
74
|
+
result_scan = i2c_Interact(speed,array_i2c_scan)
|
75
|
+
if result_scan.size != 256 then
|
76
|
+
raise TypeError, "FPGA send a wrong I2C scan result, try again , check power jumper, fix wiring , power on ? (reboot the board if needed)"
|
77
|
+
end
|
78
|
+
|
79
|
+
for i in (0..result_scan.size-1).step(2) do
|
80
|
+
#Check if ACK_ERROR
|
81
|
+
if result_scan[i] == 1 then
|
82
|
+
return_scan.push 1 #For write
|
83
|
+
return_scan.push 1 #For read
|
84
|
+
else
|
85
|
+
return_scan.push 0 #For write
|
86
|
+
return_scan.push 0 #For read
|
87
|
+
end
|
88
|
+
end
|
89
|
+
return return_scan
|
90
|
+
end
|
91
|
+
|
92
|
+
# Interact with I2C bus
|
93
|
+
# * +speed+:: I2C::KHZ_100 , I2C::KHZ_400 , I2C::KHZ_1000
|
94
|
+
# * +i2cBaseAddress+:: I2C base address / Write address (8bits)
|
95
|
+
# * +startAddress+:: Start address (included)
|
96
|
+
# * +stopAddress+:: Stop address (included)
|
97
|
+
# * +sizeMax+:: Size max of memory (important to calculate automaticly the number of byte to set address)
|
98
|
+
def i2c_Generic_Dump (*args)
|
99
|
+
parametters = HardsploitAPI.checkParametters(["speed","i2cBaseAddress","startAddress","stopAddress","sizeMax"],args)
|
100
|
+
speed = parametters[:speed]
|
101
|
+
i2cBaseAddress = parametters[:i2cBaseAddress]
|
102
|
+
startAddress = parametters[:startAddress]
|
103
|
+
stopAddress = parametters[:stopAddress]
|
104
|
+
sizeMax = parametters[:sizeMax]
|
105
|
+
|
106
|
+
if ((startAddress < 0) or (startAddress > sizeMax-1)) then
|
107
|
+
raise TypeError, "Start address can't be negative and not more than size max - 1"
|
108
|
+
end
|
109
|
+
if ((stopAddress < 0) or (stopAddress > (sizeMax-1))) then
|
110
|
+
raise TypeError, "Stop address can't be negative and not more than size max-1 because start at 0"
|
111
|
+
end
|
112
|
+
|
113
|
+
if (stopAddress <= startAddress) then
|
114
|
+
raise TypeError, "Stop address need to be greater than start address"
|
115
|
+
end
|
116
|
+
|
117
|
+
numberOfByteAddress = (((Math.log(sizeMax-1,2)).floor + 1) / 8.0).ceil
|
118
|
+
if numberOfByteAddress > 4 then
|
119
|
+
raise TypeError, "Size max must be less than 2^32 about 4Gb"
|
120
|
+
end
|
121
|
+
|
122
|
+
if numberOfByteAddress <= 0 then
|
123
|
+
raise TypeError, "There is an issue with calculating of number of byte needed"
|
124
|
+
end
|
125
|
+
|
126
|
+
packet_size = 2000 - numberOfByteAddress - 1
|
127
|
+
number_complet_packet = ( (stopAddress-startAddress+1) / packet_size).floor
|
128
|
+
size_last_packet = (stopAddress-startAddress+1) % packet_size
|
129
|
+
|
130
|
+
#SEND the first complete trame
|
131
|
+
for i in 0..number_complet_packet-1 do
|
132
|
+
packet = generate_i2c_read_command i2cBaseAddress,numberOfByteAddress+startAddress,i*packet_size,packet_size
|
133
|
+
|
134
|
+
temp = i2c_Interact(speed,packet)
|
135
|
+
case temp
|
136
|
+
when HardsploitAPI::USB_STATE::PACKET_IS_TOO_LARGE
|
137
|
+
puts "PACKET_IS_TOO_LARGE max: #{HardsploitAPI::USB::USB_TRAME_SIZE}"
|
138
|
+
when HardsploitAPI::USB_STATE::ERROR_SEND
|
139
|
+
puts "ERROR_SEND\n"
|
140
|
+
when HardsploitAPI::USB_STATE::BUSY
|
141
|
+
puts "BUSY"
|
142
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
143
|
+
puts "TIMEOUT_RECEIVE\n"
|
144
|
+
else
|
145
|
+
#Remove header, result of read command and numberOfByte Address too
|
146
|
+
consoleData ( process_dump_i2c_result( temp ) )
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
packet = generate_i2c_read_command i2cBaseAddress,numberOfByteAddress,number_complet_packet*packet_size+startAddress,size_last_packet
|
151
|
+
temp = i2c_Interact(speed,packet)
|
152
|
+
case temp
|
153
|
+
when HardsploitAPI::USB_STATE::PACKET_IS_TOO_LARGE
|
154
|
+
puts "PACKET_IS_TOO_LARGE max: #{HardsploitAPI::USB::USB_TRAME_SIZE}"
|
155
|
+
when HardsploitAPI::USB_STATE::ERROR_SEND
|
156
|
+
puts "ERROR_SEND\n"
|
157
|
+
when HardsploitAPI::USB_STATE::BUSY
|
158
|
+
puts "BUSY"
|
159
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
160
|
+
puts "TIMEOUT_RECEIVE\n"
|
161
|
+
else
|
162
|
+
#Remove header, result of read command and numberOfByte Address too
|
163
|
+
consoleData ( process_dump_i2c_result ( temp ) )
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
def process_dump_i2c_result (packet)
|
169
|
+
result = Array.new
|
170
|
+
for i in (0..packet.size-1).step(2) do
|
171
|
+
case packet[i]
|
172
|
+
when 1 #Read ACK
|
173
|
+
#Save read data
|
174
|
+
result.push packet[i+1]
|
175
|
+
when 0 #Write ACK
|
176
|
+
#Do nothing,don't save write ack
|
177
|
+
else
|
178
|
+
raise TypeError, "Error in I2C transaction, I2C dump seems to be wrong"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
return result
|
182
|
+
end
|
183
|
+
|
184
|
+
def generate_i2c_read_command ( i2cBaseAddress, numberOfByteAddress,startAddress,size)
|
185
|
+
packet = Array.new
|
186
|
+
#Push write command for start address
|
187
|
+
packet.push HardsploitAPI.lowByte(numberOfByteAddress) #size of write command
|
188
|
+
packet.push HardsploitAPI.highByte(numberOfByteAddress) #size of write command
|
189
|
+
|
190
|
+
packet.push i2cBaseAddress #push Write address
|
191
|
+
|
192
|
+
case numberOfByteAddress
|
193
|
+
when 1
|
194
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
195
|
+
when 2
|
196
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
197
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart
|
198
|
+
when 3
|
199
|
+
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
200
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
201
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
202
|
+
when 4
|
203
|
+
packet.push ((startAddress & 0xFF000000) >> 24 ) #AddStart3
|
204
|
+
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
205
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
206
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
207
|
+
else
|
208
|
+
raise TypeError, "Issue in generate_spi_read_command function when parse number of byte address"
|
209
|
+
end
|
210
|
+
|
211
|
+
#Push read command to read size data
|
212
|
+
packet.push HardsploitAPI.lowByte(size) #size of read command
|
213
|
+
packet.push HardsploitAPI.highByte(size) #size of read command
|
214
|
+
packet.push i2cBaseAddress+1 #push read address
|
215
|
+
|
216
|
+
return packet
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,229 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#===================================================
|
3
|
+
# Hardsploit API - By Opale Security
|
4
|
+
# www.opale-security.com || www.hardsploit.io
|
5
|
+
# License: GNU General Public License v3
|
6
|
+
# License URI: http://www.gnu.org/licenses/gpl.txt
|
7
|
+
#===================================================
|
8
|
+
|
9
|
+
class HardsploitAPI
|
10
|
+
public
|
11
|
+
|
12
|
+
|
13
|
+
def readManufactuerCodeMemory
|
14
|
+
write_command_Memory_WithoutMultiplexing(0x00000000,0x90) #ReadDeviceIdentifierCommand
|
15
|
+
return readByteFromMemory(1) #Read from 1 to 1 = read 1 byte at 1
|
16
|
+
end
|
17
|
+
|
18
|
+
def readDeviceIdMemory
|
19
|
+
write_command_Memory_WithoutMultiplexing(0x00000000,0x90) #ReadDeviceIdentifierCommand
|
20
|
+
return readByteFromMemory(0)#Read 0
|
21
|
+
end
|
22
|
+
|
23
|
+
def writeByteToMemory(address,value)
|
24
|
+
#Write data in word mode and read Five status register
|
25
|
+
write_command_Memory_WithoutMultiplexing(address,0x0040)
|
26
|
+
write_command_Memory_WithoutMultiplexing(address,value)
|
27
|
+
return readByteFromMemory(0)
|
28
|
+
end
|
29
|
+
|
30
|
+
def readMode
|
31
|
+
#go in read mode
|
32
|
+
write_command_Memory_WithoutMultiplexing(0x000000,0x00FF)
|
33
|
+
end
|
34
|
+
|
35
|
+
def eraseBlockMemory(blockAddress)
|
36
|
+
#Read Five Word
|
37
|
+
write_command_Memory_WithoutMultiplexing(blockAddress,0x0020) #Block erase command
|
38
|
+
statut = write_command_Memory_WithoutMultiplexing(blockAddress,0x00D0) #Confirm Block erase command
|
39
|
+
|
40
|
+
timeout = 10
|
41
|
+
# while (statut != 128 ) && (timeout >= 0)
|
42
|
+
#
|
43
|
+
# puts "#{statut} #{timeout}"
|
44
|
+
# statut = readByteFromMemory(0) #read statut register
|
45
|
+
# sleep(100)
|
46
|
+
# if timeout == 0 then
|
47
|
+
# return statut
|
48
|
+
# else
|
49
|
+
# timeout = timeout-1
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
for ty in 0..4
|
53
|
+
puts readByteFromMemory(0)
|
54
|
+
end
|
55
|
+
|
56
|
+
puts "Return timeout"
|
57
|
+
return statut
|
58
|
+
end
|
59
|
+
|
60
|
+
def clearStatusRegisterOfMemory
|
61
|
+
#Clear Statut register
|
62
|
+
write_command_Memory_WithoutMultiplexing(0x000000,0x50)
|
63
|
+
end
|
64
|
+
|
65
|
+
def unlockBlock (blockAddress)
|
66
|
+
write_command_Memory_WithoutMultiplexing(blockAddress,0x0060) #Lock Block Command
|
67
|
+
write_command_Memory_WithoutMultiplexing(blockAddress,0x00D0) #UnLock Command
|
68
|
+
return readByteFromMemory(0x000000) #read statut register
|
69
|
+
end
|
70
|
+
|
71
|
+
def write_command_Memory_WithoutMultiplexing(address,data)
|
72
|
+
packet = Array.new
|
73
|
+
packet.push 0 #low byte of lenght of trame refresh automaticly before send by usb
|
74
|
+
packet.push 0 #high byte of lenght of trame refresh automaticly before send by usb
|
75
|
+
packet.push HardsploitAPI.lowByte(USB_COMMAND::FPGA_COMMAND)
|
76
|
+
packet.push HardsploitAPI.highByte(USB_COMMAND::FPGA_COMMAND)
|
77
|
+
|
78
|
+
packet.push 0x50 #Command RAW COMMUNICATION TO FPGA FIFO
|
79
|
+
|
80
|
+
packet.push 0 #16 bits
|
81
|
+
packet.push (1500/6.66).floor #latency at 1500ns
|
82
|
+
|
83
|
+
packet.push ((address & 0xFF000000) >> 24 ) #AddStart3
|
84
|
+
packet.push ((address & 0x00FF0000) >> 16 ) #AddStart2
|
85
|
+
packet.push ((address & 0x0000FF00) >> 8 ) #AddStart1
|
86
|
+
packet.push ((address & 0x000000FF) >> 0) #AddStart0
|
87
|
+
packet.push 0x20 #Memory write command
|
88
|
+
packet.push ((data & 0xFF00) >> 8 ) #Data HIGHT BYTE
|
89
|
+
packet.push ((data & 0xFF) >> 0) #Data LOW BYTE
|
90
|
+
|
91
|
+
|
92
|
+
result = sendAndReceiveDATA(packet,1000)
|
93
|
+
if result == USB_STATE::TIMEOUT_RECEIVE then
|
94
|
+
raise "TIMEOUT"
|
95
|
+
elsif result[4] == (data & 0xFF)
|
96
|
+
|
97
|
+
return readByteFromMemory(0)
|
98
|
+
else
|
99
|
+
raise "ERROR BAD RESPONSE"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def readByteFromMemory(address)
|
104
|
+
packet = Array.new
|
105
|
+
packet.push 0 #low byte of lenght of trame refresh automaticly before send by usb
|
106
|
+
packet.push 0 #high byte of lenght of trame refresh automaticly before send by usb
|
107
|
+
packet.push HardsploitAPI.lowByte(USB_COMMAND::FPGA_COMMAND)
|
108
|
+
packet.push HardsploitAPI.highByte(USB_COMMAND::FPGA_COMMAND)
|
109
|
+
|
110
|
+
packet.push 0x50 #Command RAW COMMUNICATION TO FPGA FIFO
|
111
|
+
|
112
|
+
|
113
|
+
#16 bits
|
114
|
+
packet.push 0
|
115
|
+
packet.push (1500/6.66).floor
|
116
|
+
|
117
|
+
|
118
|
+
packet.push ((address & 0xFF000000) >> 24 ) #AddStart3
|
119
|
+
packet.push ((address & 0x00FF0000) >> 16 ) #AddStart2
|
120
|
+
packet.push ((address & 0x0000FF00) >> 8 ) #AddStart1
|
121
|
+
packet.push ((address & 0x000000FF) >> 0) #AddStart0
|
122
|
+
|
123
|
+
packet.push 0x10 #Memory read command
|
124
|
+
packet.push ((address & 0xFF000000) >> 24 ) #AddStart3
|
125
|
+
packet.push ((address & 0x00FF0000) >> 16 ) #AddStop2
|
126
|
+
packet.push ((address & 0x0000FF00) >> 8 ) #AddStop1
|
127
|
+
packet.push ((address & 0x000000FF) >> 0) #AddStop0
|
128
|
+
|
129
|
+
result = sendAndReceiveDATA(packet,1000)
|
130
|
+
|
131
|
+
if result == USB_STATE::TIMEOUT_RECEIVE then
|
132
|
+
return "TIMEOUT"
|
133
|
+
else
|
134
|
+
if result.size == 6 then
|
135
|
+
return HardsploitAPI.BytesToInt(result[4] , result[5])
|
136
|
+
else
|
137
|
+
raise "BAD RESPONSE"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
# Read parallele memory in asynchronous mode (blocking function) but callBack data is used to receive packet
|
147
|
+
# * +addressStart+:: 32 bits address
|
148
|
+
# * +addressStop+:: 32 bits address
|
149
|
+
# * +bits8_or_bits16_DataSize+:: 0 for 8 bits operation & 1 for 16 bits operation
|
150
|
+
# * +latency+:: latency in ns range 7ns to 1600ns=1,6ms
|
151
|
+
# Return USB_STATE End with TIMEOUT_RECEIVE but need to check if received the right number of bytes to ensure all is correct
|
152
|
+
def read_Memory_WithoutMultiplexing(*args)
|
153
|
+
parametters = HardsploitAPI.checkParametters(["addressStart","addressStop","bits8_or_bits16_DataSize","latency"],args)
|
154
|
+
addressStart = parametters[:addressStart]
|
155
|
+
addressStop = parametters[:addressStop]
|
156
|
+
bits8_or_bits16_DataSize = parametters[:bits8_or_bits16_DataSize]
|
157
|
+
latency = parametters[:latency]
|
158
|
+
|
159
|
+
|
160
|
+
numberOfByteReaded = 0
|
161
|
+
packet = Array.new
|
162
|
+
packet.push 0 #low byte of lenght of trame refresh automaticly before send by usb
|
163
|
+
packet.push 0 #high byte of lenght of trame refresh automaticly before send by usb
|
164
|
+
packet.push HardsploitAPI.lowByte(USB_COMMAND::FPGA_COMMAND)
|
165
|
+
packet.push HardsploitAPI.highByte(USB_COMMAND::FPGA_COMMAND)
|
166
|
+
|
167
|
+
packet.push 0x50 #Command RAW COMMUNICATION TO FPGA FIFO
|
168
|
+
|
169
|
+
#Chek if 8bits or 16 bits
|
170
|
+
if bits8_or_bits16_DataSize == true then
|
171
|
+
packet.push 1
|
172
|
+
else
|
173
|
+
packet.push 0
|
174
|
+
end
|
175
|
+
|
176
|
+
#Check latency value
|
177
|
+
if ((latency >= 7) and (latency <= 1600)) then
|
178
|
+
packet.push (latency/6.66).floor
|
179
|
+
else
|
180
|
+
raise TypeError, 'Latency value must be from 7 to 1695'
|
181
|
+
end
|
182
|
+
|
183
|
+
#Check address
|
184
|
+
if (addressStop <= addressStart ) then
|
185
|
+
raise TypeError, 'Stop address is less than start address'
|
186
|
+
end
|
187
|
+
|
188
|
+
packet.push ((addressStart & 0xFF000000) >> 24 ) #AddStart3
|
189
|
+
packet.push ((addressStart & 0x00FF0000) >> 16 ) #AddStart2
|
190
|
+
packet.push ((addressStart & 0x0000FF00) >> 8 ) #AddStart1
|
191
|
+
packet.push ((addressStart & 0x000000FF) >> 0) #AddStart0
|
192
|
+
|
193
|
+
packet.push 0x10 #Memory read command
|
194
|
+
packet.push ((addressStop & 0xFF000000) >> 24 ) #AddStart3
|
195
|
+
packet.push ((addressStop & 0x00FF0000) >> 16 ) #AddStop2
|
196
|
+
packet.push ((addressStop & 0x0000FF00) >> 8 ) #AddStop1
|
197
|
+
packet.push ((addressStop & 0x000000FF) >> 0) #AddStop0
|
198
|
+
|
199
|
+
sendPacket(packet)
|
200
|
+
|
201
|
+
if bits8_or_bits16_DataSize then
|
202
|
+
sizeCalculated = (addressStop-addressStart+1)
|
203
|
+
else
|
204
|
+
sizeCalculated = (addressStop-addressStart+1)*2
|
205
|
+
end
|
206
|
+
|
207
|
+
numberOfByteReaded = 0
|
208
|
+
while true
|
209
|
+
tmp= receiveDATA(2000)
|
210
|
+
case tmp
|
211
|
+
when HardsploitAPI::USB_STATE::BUSY
|
212
|
+
raise "USB_STATE::BUSY"
|
213
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
214
|
+
raise "Timeout"
|
215
|
+
else
|
216
|
+
#remove header (4 bytes 2 for size 2 for type of command)
|
217
|
+
tmp = tmp.bytes.drop(4)
|
218
|
+
numberOfByteReaded = numberOfByteReaded + tmp.size
|
219
|
+
consoleData(tmp)
|
220
|
+
|
221
|
+
puts "Receive #{numberOfByteReaded} of #{sizeCalculated}"
|
222
|
+
if numberOfByteReaded >= sizeCalculated then
|
223
|
+
#Exit because we received all data
|
224
|
+
return
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#===================================================
|
3
|
+
# Hardsploit API - By Opale Security
|
4
|
+
# www.opale-security.com || www.hardsploit.io
|
5
|
+
# License: GNU General Public License v3
|
6
|
+
# License URI: http://www.gnu.org/licenses/gpl.txt
|
7
|
+
#===================================================
|
8
|
+
|
9
|
+
class HardsploitAPI
|
10
|
+
public
|
11
|
+
|
12
|
+
# SPI interact
|
13
|
+
# * +mode+:: SPI mode 0,1,2,3
|
14
|
+
# * +speed+:: Range 1-255 SPI clock = 150Mhz / (2*speed) tested from 3 to 255 (25Mhz to about 0.3Khz)
|
15
|
+
# * +payload+:: Byte array want to send
|
16
|
+
# * Return SPI data received
|
17
|
+
def spi_Interact(*args)
|
18
|
+
parametters = HardsploitAPI.checkParametters(["mode","speed","payload"],args)
|
19
|
+
mode = parametters[:mode]
|
20
|
+
speed = parametters[:speed]
|
21
|
+
payload = parametters[:payload]
|
22
|
+
|
23
|
+
if (mode < 0) and (mode >3) then
|
24
|
+
raise TypeError, 'Mode must be between 0 and 3'
|
25
|
+
end
|
26
|
+
if (speed <= 2) and (speed >256) then
|
27
|
+
raise TypeError, 'Speed must be between 3 and 255'
|
28
|
+
end
|
29
|
+
|
30
|
+
if (payload.size > 4000) then
|
31
|
+
raise TypeError, 'Size of the data need to be less than 4000'
|
32
|
+
end
|
33
|
+
|
34
|
+
packet = Array.new
|
35
|
+
packet.push 0 #low byte of lenght of trame refresh automaticly before send by usb
|
36
|
+
packet.push 0 #high byte of lenght of trame refresh automaticly before send by usb
|
37
|
+
packet.push HardsploitAPI.lowByte(USB_COMMAND::FPGA_COMMAND)
|
38
|
+
packet.push HardsploitAPI.highByte(USB_COMMAND::FPGA_COMMAND)
|
39
|
+
|
40
|
+
packet.push 0x50 #Command RAW COMMUNICATION TO FPGA FIFO
|
41
|
+
|
42
|
+
packet.push mode #Add mode
|
43
|
+
packet.push speed #Add speed
|
44
|
+
packet.concat payload #Add data
|
45
|
+
|
46
|
+
sendPacket packet
|
47
|
+
|
48
|
+
tmp= receiveDATA(1000)
|
49
|
+
case tmp
|
50
|
+
when HardsploitAPI::USB_STATE::BUSY
|
51
|
+
return USB_STATE::BUSY
|
52
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
53
|
+
return USB_STATE::TIMEOUT_RECEIVE
|
54
|
+
else
|
55
|
+
#remove header (4 bytes 2 for size 2 for type of command)
|
56
|
+
return tmp.bytes.drop(4)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Spi generic dump
|
61
|
+
# * +mode+:: SPI mode 0,1,2,3
|
62
|
+
# * +speed+:: Range 1-255 SPI clock = 150Mhz / (2*speed) tested from 3 to 255 (25Mhz to about 0.3Khz)
|
63
|
+
# * +readSpiCommand+:: The read command
|
64
|
+
# * +startAddress+:: Start address (included)
|
65
|
+
# * +stopAddress+:: Stop address (included)
|
66
|
+
# * +sizeMax+:: Size max of memory (important to calculate automaticly the number of byte to set address)
|
67
|
+
def spi_Generic_Dump (*args)
|
68
|
+
parametters = HardsploitAPI.checkParametters(["mode","speed","readSpiCommand","startAddress","stopAddress","sizeMax"],args)
|
69
|
+
mode = parametters[:mode]
|
70
|
+
speed = parametters[:speed]
|
71
|
+
readSpiCommand = parametters[:readSpiCommand]
|
72
|
+
startAddress = parametters[:startAddress]
|
73
|
+
stopAddress = parametters[:stopAddress]
|
74
|
+
sizeMax = parametters[:sizeMax]
|
75
|
+
|
76
|
+
if ((startAddress < 0) or (startAddress > sizeMax-1)) then
|
77
|
+
raise TypeError, "Start address can't be negative and not more than size max - 1"
|
78
|
+
end
|
79
|
+
if ((stopAddress < 0) or (stopAddress > (sizeMax-1))) then
|
80
|
+
raise TypeError, "Stop address can't be negative and not more than size max-1 because start at 0"
|
81
|
+
end
|
82
|
+
|
83
|
+
if (stopAddress < startAddress) then
|
84
|
+
raise TypeError, "Stop address need to be greater than start address"
|
85
|
+
end
|
86
|
+
|
87
|
+
numberOfByteAddress = (((Math.log(sizeMax-1,2)).floor + 1) / 8.0).ceil
|
88
|
+
if numberOfByteAddress > 4 then
|
89
|
+
raise TypeError, "Size max must be less than 2^32 about 4Gb"
|
90
|
+
end
|
91
|
+
|
92
|
+
if numberOfByteAddress <= 0 then
|
93
|
+
raise TypeError, "There is an issue with calculating of number of byte needed"
|
94
|
+
end
|
95
|
+
|
96
|
+
packet_size = 4000 - numberOfByteAddress - 1
|
97
|
+
number_complet_packet = ( (stopAddress-startAddress+1) / packet_size).floor
|
98
|
+
size_last_packet = (stopAddress-startAddress+1) % packet_size
|
99
|
+
|
100
|
+
#SEND the first complete trame
|
101
|
+
for i in 0..number_complet_packet-1 do
|
102
|
+
packet = generate_spi_read_command numberOfByteAddress,readSpiCommand,i*packet_size+startAddress,packet_size
|
103
|
+
|
104
|
+
temp = spi_Interact(mode,speed,packet)
|
105
|
+
case temp
|
106
|
+
when HardsploitAPI::USB_STATE::PACKET_IS_TOO_LARGE
|
107
|
+
puts "PACKET_IS_TOO_LARGE max: #{HardsploitAPI::USB::USB_TRAME_SIZE}"
|
108
|
+
when HardsploitAPI::USB_STATE::ERROR_SEND
|
109
|
+
puts "ERROR_SEND\n"
|
110
|
+
when HardsploitAPI::USB_STATE::BUSY
|
111
|
+
puts "BUSY"
|
112
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
113
|
+
puts "TIMEOUT_RECEIVE\n"
|
114
|
+
else
|
115
|
+
#Remove header, result of read command and numberOfByte Address too
|
116
|
+
puts "receive real size #{temp.size}"
|
117
|
+
consoleData temp.drop(numberOfByteAddress+1)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
packet = generate_spi_read_command numberOfByteAddress,readSpiCommand,number_complet_packet*packet_size+startAddress,size_last_packet
|
122
|
+
temp = spi_Interact(mode,speed,packet)
|
123
|
+
case temp
|
124
|
+
when HardsploitAPI::USB_STATE::PACKET_IS_TOO_LARGE
|
125
|
+
puts "PACKET_IS_TOO_LARGE max: #{HardsploitAPI::USB::USB_TRAME_SIZE}"
|
126
|
+
when HardsploitAPI::USB_STATE::ERROR_SEND
|
127
|
+
puts "ERROR_SEND\n"
|
128
|
+
when HardsploitAPI::USB_STATE::BUSY
|
129
|
+
puts "BUSY"
|
130
|
+
when HardsploitAPI::USB_STATE::TIMEOUT_RECEIVE
|
131
|
+
puts "TIMEOUT_RECEIVE\n"
|
132
|
+
else
|
133
|
+
#Remove header, result of read command and numberOfByte Address too
|
134
|
+
puts "receive real size #{temp.size}"
|
135
|
+
consoleData temp.drop(numberOfByteAddress+1)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
protected
|
140
|
+
def generate_spi_read_command ( numberOfByteAddress,readSpiCommand,startAddress,size)
|
141
|
+
packet = Array.new
|
142
|
+
|
143
|
+
#Push read command
|
144
|
+
packet.push readSpiCommand
|
145
|
+
|
146
|
+
case numberOfByteAddress
|
147
|
+
when 1
|
148
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
149
|
+
|
150
|
+
when 2
|
151
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
152
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
153
|
+
|
154
|
+
when 3
|
155
|
+
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
156
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
157
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
158
|
+
|
159
|
+
when 4
|
160
|
+
packet.push ((startAddress & 0xFF000000) >> 24 ) #AddStart3
|
161
|
+
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
162
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
163
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
164
|
+
else
|
165
|
+
raise TypeError, "Issue in generate_spi_read_command function when parse number of byte address"
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
#put N dummy byte to read size data
|
170
|
+
packet.push *Array.new(size, 0)
|
171
|
+
|
172
|
+
puts " Send real size #{packet.size}"
|
173
|
+
if packet.size > 4000 then
|
174
|
+
raise TypeError, "Too many byte to send in spi mode not more than 4000 is needed"
|
175
|
+
end
|
176
|
+
|
177
|
+
return packet
|
178
|
+
end
|
179
|
+
end
|