hardsploit_gui 2.3 → 2.4.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 +4 -4
- data/README.md +22 -22
- data/Rakefile +1 -1
- data/bin/hardsploit_gui +3 -3
- data/lib/Firmwares/FPGA/I2C/I2C_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_I2C_INTERACT.rpd +0 -0
- data/lib/Firmwares/FPGA/PARALLEL/NO_MUX_PARALLEL_MEMORY/HARDSPLOIT_FIRMWARE_FPGA_NO_MUX_PARALLEL_MEMORY.rpd +0 -0
- data/lib/Firmwares/FPGA/SPI/SPI_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_SPI_INTERACT.rpd +0 -0
- data/lib/Firmwares/FPGA/SPI/SPI_SNIFFER/HARDSPLOIT_FIRMWARE_FPGA_SPI_SNIFFER.rpd +0 -0
- data/lib/Firmwares/FPGA/SWD/SWD_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_SWD_INTERACT.rpd +0 -0
- data/lib/Firmwares/FPGA/UART/UART_INTERACT/HARDSPLOIT_FIRMWARE_FPGA_UART_INTERACT.rpd +0 -0
- data/lib/Firmwares/FPGA/VersionFPGA.rb +5 -5
- data/lib/Firmwares/UC/VersionUC.rb +12 -12
- data/lib/HardsploitAPI/Core/HardsploitAPI.rb +210 -210
- data/lib/HardsploitAPI/Core/HardsploitAPI_CONSTANT.rb +150 -150
- data/lib/HardsploitAPI/Core/HardsploitAPI_ERROR.rb +109 -109
- data/lib/HardsploitAPI/Core/HardsploitAPI_FIRMWARE.rb +305 -305
- data/lib/HardsploitAPI/Core/HardsploitAPI_PROGRESS.rb +28 -28
- data/lib/HardsploitAPI/Core/HardsploitAPI_USB_COMMUNICATION.rb +166 -166
- data/lib/HardsploitAPI/Modules/I2C/HardsploitAPI_I2C.rb +356 -356
- data/lib/HardsploitAPI/Modules/NO_MUX_PARALLEL_MEMORY/HardsploitAPI_NO_MUX_PARALLEL_MEMORY.rb +206 -206
- data/lib/HardsploitAPI/Modules/NRF24L01/HardsploitAPI_NRF24L01.rb +306 -306
- data/lib/HardsploitAPI/Modules/SPI/HardsploitAPI_SPI.rb +340 -340
- data/lib/HardsploitAPI/Modules/SPI_SNIFFER/HardsploitAPI_SPI_SNIFFER.rb +83 -83
- data/lib/HardsploitAPI/Modules/SWD/HardsploitAPI_SWD.rb +367 -367
- data/lib/HardsploitAPI/Modules/SWD/HardsploitAPI_SWD_DEBUG.rb +89 -89
- data/lib/HardsploitAPI/Modules/SWD/HardsploitAPI_SWD_MEM_AP.rb +61 -61
- data/lib/HardsploitAPI/Modules/SWD/HardsploitAPI_SWD_STM32.rb +121 -121
- data/lib/HardsploitAPI/Modules/TEST/HardsploitAPI_TEST_INTERACT.rb +98 -98
- data/lib/HardsploitAPI/Modules/UART/HardsploitAPI_UART.rb +196 -196
- data/lib/Hardsploit_gui.rb +96 -96
- data/lib/LICENSE.txt +674 -674
- data/lib/README.md +22 -22
- data/lib/TRADEMARK +2 -2
- data/lib/class/Chip_editor.rb +304 -304
- data/lib/class/Chip_management.rb +496 -496
- data/lib/class/Command_editor.rb +216 -216
- data/lib/class/Command_table.rb +233 -233
- data/lib/class/Console.rb +26 -26
- data/lib/class/ErrorMsg.rb +312 -312
- data/lib/class/Export.rb +140 -140
- data/lib/class/Export_manager.rb +124 -124
- data/lib/class/Firmware.rb +70 -70
- data/lib/class/Generic_commands.rb +260 -260
- data/lib/class/{i2c → I2C}/I2c_command.rb +51 -51
- data/lib/class/{i2c → I2C}/I2c_export.rb +95 -95
- data/lib/class/{i2c → I2C}/I2c_import.rb +117 -117
- data/lib/class/{i2c → I2C}/I2c_scanner.rb +114 -114
- data/lib/class/{i2c → I2C}/I2c_settings.rb +148 -148
- data/lib/class/Import.rb +193 -193
- data/lib/class/{parallel → PARALLEL}/Parallel_export.rb +118 -118
- data/lib/class/{parallel → PARALLEL}/Parallel_import.rb +113 -113
- data/lib/class/{parallel → PARALLEL}/Parallel_settings.rb +81 -81
- data/lib/class/Progress_bar.rb +32 -32
- data/lib/class/{spi → SPI}/Spi_export.rb +108 -108
- data/lib/class/{spi → SPI}/Spi_import.rb +159 -159
- data/lib/class/{spi → SPI}/Spi_settings.rb +108 -108
- data/lib/class/{spi → SPI}/Spi_sniffer.rb +101 -101
- data/lib/class/Signal_mapper.rb +120 -120
- data/lib/class/Wire_helper.rb +230 -230
- data/lib/class/swd/Swd.rb +125 -125
- data/lib/class/swd/Swd_scanner.rb +121 -121
- data/lib/class/swd/Swd_settings.rb +76 -76
- data/lib/class/uart/Uart_baudrate.rb +62 -62
- data/lib/class/uart/Uart_console.rb +115 -115
- data/lib/class/uart/Uart_settings.rb +102 -102
- data/lib/db/associations.rb +138 -138
- data/lib/db/database.rb +4 -4
- data/lib/db/development.sqlite3 +0 -0
- data/lib/db/migrate/004_create_manufacturers.rb +13 -13
- data/lib/db/migrate/005_create_packages.rb +13 -13
- data/lib/db/migrate/006_create_chip_types.rb +11 -11
- data/lib/db/migrate/007_create_buses.rb +11 -11
- data/lib/db/migrate/008_create_signals.rb +14 -14
- data/lib/db/migrate/009_create_chips.rb +25 -25
- data/lib/db/migrate/010_create_commands.rb +21 -21
- data/lib/db/migrate/011_create_bytes.rb +19 -19
- data/lib/db/migrate/012_create_i2c_settings.rb +21 -21
- data/lib/db/migrate/013_create_spi_settings.rb +26 -26
- data/lib/db/migrate/014_create_parallel_settings.rb +21 -21
- data/lib/db/migrate/015_create_pins.rb +19 -19
- data/lib/db/migrate/016_create_uses.rb +17 -17
- data/lib/db/migrate/017_create_swd_settings.rb +19 -19
- data/lib/db/migrate/018_create_uart_settings.rb +22 -22
- data/lib/db/schema.rb +157 -157
- data/lib/db/seeds.rb +161 -161
- data/lib/gui/gui_chip_editor.rb +349 -349
- data/lib/gui/gui_chip_management.rb +377 -377
- data/lib/gui/gui_command_editor.rb +219 -219
- data/lib/gui/gui_export.rb +132 -132
- data/lib/gui/gui_export_manager.rb +93 -93
- data/lib/gui/gui_generic_commands.rb +202 -202
- data/lib/gui/gui_generic_export.rb +164 -164
- data/lib/gui/gui_generic_import.rb +142 -142
- data/lib/gui/gui_i2c_command.rb +116 -116
- data/lib/gui/gui_i2c_settings.rb +230 -230
- data/lib/gui/gui_import.rb +131 -131
- data/lib/gui/gui_parallel_settings.rb +195 -195
- data/lib/gui/gui_progress_bar.rb +85 -85
- data/lib/gui/gui_signal_mapper.rb +121 -121
- data/lib/gui/gui_signal_scanner.rb +146 -146
- data/lib/gui/gui_spi_import.rb +126 -126
- data/lib/gui/gui_spi_settings.rb +313 -313
- data/lib/gui/gui_spi_sniffer.rb +112 -112
- data/lib/gui/gui_swd_settings.rb +166 -166
- data/lib/gui/gui_uart_baudrate.rb +114 -114
- data/lib/gui/gui_uart_console.rb +164 -164
- data/lib/gui/gui_uart_settings.rb +243 -243
- data/lib/gui/gui_wire_helper.rb +99 -99
- data/lib/gui_designer/gui_chip_editor.ui +549 -549
- data/lib/gui_designer/gui_chip_management.ui +886 -886
- data/lib/gui_designer/gui_command_editor.ui +350 -350
- data/lib/gui_designer/gui_export.ui +171 -171
- data/lib/gui_designer/gui_export_manager.ui +115 -115
- data/lib/gui_designer/gui_generic_commands.ui +342 -342
- data/lib/gui_designer/gui_generic_export.ui +202 -202
- data/lib/gui_designer/gui_generic_import.ui +165 -165
- data/lib/gui_designer/gui_i2c_command.ui +148 -148
- data/lib/gui_designer/gui_i2c_settings.ui +292 -292
- data/lib/gui_designer/gui_import.ui +168 -168
- data/lib/gui_designer/gui_parallel_settings.ui +247 -247
- data/lib/gui_designer/gui_progress_bar.ui +86 -86
- data/lib/gui_designer/gui_signal_mapper.ui +179 -179
- data/lib/gui_designer/gui_signal_scanner.ui +261 -261
- data/lib/gui_designer/gui_spi_settings.ui +446 -446
- data/lib/gui_designer/gui_spi_sniffer.ui +156 -156
- data/lib/gui_designer/gui_swd_settings.ui +189 -189
- data/lib/gui_designer/gui_uart_baudrate.ui +161 -161
- data/lib/gui_designer/gui_uart_console.ui +284 -284
- data/lib/gui_designer/gui_uart_settings.ui +280 -280
- data/lib/gui_designer/gui_wire_helper.ui +117 -117
- data/lib/images/search.png +0 -0
- data/lib/logs/error.log +0 -63
- data/lib/models/bus.rb +19 -19
- data/lib/models/byte.rb +29 -29
- data/lib/models/chip.rb +41 -41
- data/lib/models/chip_type.rb +14 -14
- data/lib/models/command.rb +20 -20
- data/lib/models/i2c_setting.rb +41 -41
- data/lib/models/manufacturer.rb +14 -14
- data/lib/models/package.rb +26 -26
- data/lib/models/parallel_setting.rb +37 -37
- data/lib/models/pin.rb +14 -14
- data/lib/models/signall.rb +20 -20
- data/lib/models/spi_setting.rb +67 -67
- data/lib/models/swd_setting.rb +25 -25
- data/lib/models/uart_setting.rb +52 -52
- data/lib/models/use.rb +6 -6
- data/lib/startHardsploit.rb +10 -10
- metadata +14 -14
@@ -1,28 +1,28 @@
|
|
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
|
-
class HardsploitProgress
|
11
|
-
def initialize(percent,timeElasped)
|
12
|
-
@Percent = percent
|
13
|
-
@TimeElasped = timeElasped
|
14
|
-
end
|
15
|
-
def getPercent
|
16
|
-
return @Percent
|
17
|
-
end
|
18
|
-
def setPercent(percent)
|
19
|
-
@Percent = percent
|
20
|
-
end
|
21
|
-
def getTimeElasped
|
22
|
-
return @TimeElasped
|
23
|
-
end
|
24
|
-
def setTimeElasped(timeElasped)
|
25
|
-
@TimeElasped = timeElasped
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
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
|
+
class HardsploitProgress
|
11
|
+
def initialize(percent,timeElasped)
|
12
|
+
@Percent = percent
|
13
|
+
@TimeElasped = timeElasped
|
14
|
+
end
|
15
|
+
def getPercent
|
16
|
+
return @Percent
|
17
|
+
end
|
18
|
+
def setPercent(percent)
|
19
|
+
@Percent = percent
|
20
|
+
end
|
21
|
+
def getTimeElasped
|
22
|
+
return @TimeElasped
|
23
|
+
end
|
24
|
+
def setTimeElasped(timeElasped)
|
25
|
+
@TimeElasped = timeElasped
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,166 +1,166 @@
|
|
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
|
-
require "benchmark"
|
10
|
-
class HardsploitAPI
|
11
|
-
public
|
12
|
-
|
13
|
-
# Obtain the number of hardsploit connected to PC
|
14
|
-
# Return number
|
15
|
-
def self.getNumberOfBoardAvailable
|
16
|
-
return LIBUSB::Context.new.devices(:idVendor => 0x0483, :idProduct => 0xFFFF).size
|
17
|
-
end
|
18
|
-
|
19
|
-
# Connect board and get an instance to work with
|
20
|
-
# Return USB_STATE
|
21
|
-
def connect
|
22
|
-
@usb = LIBUSB::Context.new
|
23
|
-
@devices = @usb.devices(:idVendor => 0x0483, :idProduct => 0xFFFF)
|
24
|
-
|
25
|
-
if @devices.size == 0 then
|
26
|
-
@device = nil
|
27
|
-
@dev = nil
|
28
|
-
raise ERROR::HARDSPLOIT_NOT_FOUND
|
29
|
-
else
|
30
|
-
if @@id >= @devices.size then
|
31
|
-
raise ERROR::HARDSPLOIT_NOT_FOUND
|
32
|
-
else
|
33
|
-
begin
|
34
|
-
if @dev == nil then
|
35
|
-
@dev = @devices[@@id].open
|
36
|
-
if RUBY_PLATFORM=~/linux/i && @dev.kernel_driver_active?(0)
|
37
|
-
@dev.detach_kernel_driver(0)
|
38
|
-
end
|
39
|
-
@dev.claim_interface(0)
|
40
|
-
end
|
41
|
-
self.startFPGA
|
42
|
-
sleep(0.1)
|
43
|
-
self.setStatutLed(led:USB_COMMAND::GREEN_LED,state:true);
|
44
|
-
rescue
|
45
|
-
raise ERROR::USB_ERROR
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def reconncet
|
52
|
-
@usb = LIBUSB::Context.new
|
53
|
-
@devices = @usb.devices(:idVendor => 0x0483, :idProduct => 0xFFFF)
|
54
|
-
if @devices.size == 0 then
|
55
|
-
@device = nil
|
56
|
-
@dev = nil
|
57
|
-
raise ERROR::HARDSPLOIT_NOT_FOUND
|
58
|
-
else
|
59
|
-
begin
|
60
|
-
@dev = @devices[@@id].open
|
61
|
-
if RUBY_PLATFORM=~/linux/i && @dev.kernel_driver_active?(0)
|
62
|
-
@dev.detach_kernel_driver(0)
|
63
|
-
end
|
64
|
-
@dev.claim_interface(0)
|
65
|
-
self.startFPGA
|
66
|
-
sleep(0.1)
|
67
|
-
self.setStatutLed(led:USB_COMMAND::GREEN_LED,state:true);
|
68
|
-
|
69
|
-
rescue
|
70
|
-
raise ERROR::USB_ERROR
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Obtain low byte of a word
|
76
|
-
# * +word+:: 16 bit word
|
77
|
-
# Return low byte of the word
|
78
|
-
def self.lowByte(word:)
|
79
|
-
return word & 0xFF
|
80
|
-
end
|
81
|
-
|
82
|
-
# Obtain high byte of a word
|
83
|
-
# * +word+:: 16 bit word
|
84
|
-
# Return high byte of the word
|
85
|
-
def self.highByte(word:)
|
86
|
-
return (word & 0xFF00) >> 8
|
87
|
-
end
|
88
|
-
|
89
|
-
# Obtain high byte of a word
|
90
|
-
# * +lByte+:: low byte
|
91
|
-
# * +hByte+:: high byte
|
92
|
-
# Return 16 bits integer concatenate with low and high bytes
|
93
|
-
def self.BytesToInt(lByte:,hByte:)
|
94
|
-
return (lByte + (hByte<<8))
|
95
|
-
end
|
96
|
-
|
97
|
-
|
98
|
-
# Send data and wait to receive response
|
99
|
-
# * +packet_send+:: array of byte
|
100
|
-
# * +timeout+:: timeout to read response (ms)
|
101
|
-
# Return USB_STATE or array with response (improve soon with exception)
|
102
|
-
def sendAndReceiveDATA(packet_send,timeout)
|
103
|
-
time = Time.new
|
104
|
-
begin
|
105
|
-
sendPacket(packet_send)
|
106
|
-
received_data = @dev.bulk_transfer(:endpoint=>IN_ENDPOINT, :dataIn=>USB::USB_TRAME_SIZE, :timeout=>timeout)
|
107
|
-
consoleSpeed "RECEIVE #{((received_data.bytes.to_a.size/(Time.new-time))).round(2)}Bytes/s #{(received_data.bytes.to_a.size)}Bytes in #{(Time.new-time).round(4)} s"
|
108
|
-
return received_data.bytes.to_a
|
109
|
-
rescue LIBUSB::ERROR_NO_DEVICE
|
110
|
-
raise ERROR::HARDSPLOIT_NOT_FOUND
|
111
|
-
rescue
|
112
|
-
raise ERROR::USB_ERROR
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
# Wait to receive data
|
117
|
-
# * +timeout+:: timeout to read response (ms)
|
118
|
-
# Return USB_STATE or array with response (improve soon with exception)
|
119
|
-
def receiveDATA(timeout)
|
120
|
-
begin
|
121
|
-
received_data = @dev.bulk_transfer(:endpoint=>IN_ENDPOINT, :dataIn=>USB::USB_TRAME_SIZE, :timeout=>timeout)
|
122
|
-
return received_data
|
123
|
-
rescue LIBUSB::ERROR_NO_DEVICE
|
124
|
-
raise ERROR::USB_ERROR
|
125
|
-
rescue LIBUSB::ERROR_NO_DEVICE
|
126
|
-
raise ERROR::HARDSPLOIT_NOT_FOUND
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
# Send USB packet
|
131
|
-
# * +packet+:: array with bytes
|
132
|
-
# Return number of byte sent
|
133
|
-
def sendPacket(packet_send)
|
134
|
-
|
135
|
-
begin
|
136
|
-
if packet_send.size <= 8191 then
|
137
|
-
|
138
|
-
packet_send[0] = HardsploitAPI.lowByte(word:packet_send.size)
|
139
|
-
packet_send[1] = HardsploitAPI.highByte(word:packet_send.size)
|
140
|
-
|
141
|
-
#if a multiple of packet size add a value to explicit the end of trame
|
142
|
-
if packet_send.size % 64 ==0 then
|
143
|
-
packet_send.push 0
|
144
|
-
end
|
145
|
-
|
146
|
-
number_of_data_send = 0
|
147
|
-
time = Benchmark.realtime do
|
148
|
-
number_of_data_send = @dev.bulk_transfer(:endpoint=>OUT_ENDPOINT, :dataOut=>packet_send.pack('c*'),:timeout=>3000)
|
149
|
-
end
|
150
|
-
consoleSpeed "SEND #{((number_of_data_send/time)).round(2)}Bytes/s SEND #{(number_of_data_send)}Bytes in #{time.round(4)} s"
|
151
|
-
if number_of_data_send == packet_send.size then
|
152
|
-
return number_of_data_send
|
153
|
-
else
|
154
|
-
raise ERROR::USB_ERROR
|
155
|
-
end
|
156
|
-
else
|
157
|
-
raise ERROR::USB_ERROR
|
158
|
-
end
|
159
|
-
rescue LIBUSB::ERROR_NO_DEVICE
|
160
|
-
#TRY TO RECONNECT maybe error due to disconnecting and reconnecting board
|
161
|
-
reconncet
|
162
|
-
rescue
|
163
|
-
raise ERROR::USB_ERROR
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
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
|
+
require "benchmark"
|
10
|
+
class HardsploitAPI
|
11
|
+
public
|
12
|
+
|
13
|
+
# Obtain the number of hardsploit connected to PC
|
14
|
+
# Return number
|
15
|
+
def self.getNumberOfBoardAvailable
|
16
|
+
return LIBUSB::Context.new.devices(:idVendor => 0x0483, :idProduct => 0xFFFF).size
|
17
|
+
end
|
18
|
+
|
19
|
+
# Connect board and get an instance to work with
|
20
|
+
# Return USB_STATE
|
21
|
+
def connect
|
22
|
+
@usb = LIBUSB::Context.new
|
23
|
+
@devices = @usb.devices(:idVendor => 0x0483, :idProduct => 0xFFFF)
|
24
|
+
|
25
|
+
if @devices.size == 0 then
|
26
|
+
@device = nil
|
27
|
+
@dev = nil
|
28
|
+
raise ERROR::HARDSPLOIT_NOT_FOUND
|
29
|
+
else
|
30
|
+
if @@id >= @devices.size then
|
31
|
+
raise ERROR::HARDSPLOIT_NOT_FOUND
|
32
|
+
else
|
33
|
+
begin
|
34
|
+
if @dev == nil then
|
35
|
+
@dev = @devices[@@id].open
|
36
|
+
if RUBY_PLATFORM=~/linux/i && @dev.kernel_driver_active?(0)
|
37
|
+
@dev.detach_kernel_driver(0)
|
38
|
+
end
|
39
|
+
@dev.claim_interface(0)
|
40
|
+
end
|
41
|
+
self.startFPGA
|
42
|
+
sleep(0.1)
|
43
|
+
self.setStatutLed(led:USB_COMMAND::GREEN_LED,state:true);
|
44
|
+
rescue
|
45
|
+
raise ERROR::USB_ERROR
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def reconncet
|
52
|
+
@usb = LIBUSB::Context.new
|
53
|
+
@devices = @usb.devices(:idVendor => 0x0483, :idProduct => 0xFFFF)
|
54
|
+
if @devices.size == 0 then
|
55
|
+
@device = nil
|
56
|
+
@dev = nil
|
57
|
+
raise ERROR::HARDSPLOIT_NOT_FOUND
|
58
|
+
else
|
59
|
+
begin
|
60
|
+
@dev = @devices[@@id].open
|
61
|
+
if RUBY_PLATFORM=~/linux/i && @dev.kernel_driver_active?(0)
|
62
|
+
@dev.detach_kernel_driver(0)
|
63
|
+
end
|
64
|
+
@dev.claim_interface(0)
|
65
|
+
self.startFPGA
|
66
|
+
sleep(0.1)
|
67
|
+
self.setStatutLed(led:USB_COMMAND::GREEN_LED,state:true);
|
68
|
+
|
69
|
+
rescue
|
70
|
+
raise ERROR::USB_ERROR
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Obtain low byte of a word
|
76
|
+
# * +word+:: 16 bit word
|
77
|
+
# Return low byte of the word
|
78
|
+
def self.lowByte(word:)
|
79
|
+
return word & 0xFF
|
80
|
+
end
|
81
|
+
|
82
|
+
# Obtain high byte of a word
|
83
|
+
# * +word+:: 16 bit word
|
84
|
+
# Return high byte of the word
|
85
|
+
def self.highByte(word:)
|
86
|
+
return (word & 0xFF00) >> 8
|
87
|
+
end
|
88
|
+
|
89
|
+
# Obtain high byte of a word
|
90
|
+
# * +lByte+:: low byte
|
91
|
+
# * +hByte+:: high byte
|
92
|
+
# Return 16 bits integer concatenate with low and high bytes
|
93
|
+
def self.BytesToInt(lByte:,hByte:)
|
94
|
+
return (lByte + (hByte<<8))
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
# Send data and wait to receive response
|
99
|
+
# * +packet_send+:: array of byte
|
100
|
+
# * +timeout+:: timeout to read response (ms)
|
101
|
+
# Return USB_STATE or array with response (improve soon with exception)
|
102
|
+
def sendAndReceiveDATA(packet_send,timeout)
|
103
|
+
time = Time.new
|
104
|
+
begin
|
105
|
+
sendPacket(packet_send)
|
106
|
+
received_data = @dev.bulk_transfer(:endpoint=>IN_ENDPOINT, :dataIn=>USB::USB_TRAME_SIZE, :timeout=>timeout)
|
107
|
+
consoleSpeed "RECEIVE #{((received_data.bytes.to_a.size/(Time.new-time))).round(2)}Bytes/s #{(received_data.bytes.to_a.size)}Bytes in #{(Time.new-time).round(4)} s"
|
108
|
+
return received_data.bytes.to_a
|
109
|
+
rescue LIBUSB::ERROR_NO_DEVICE
|
110
|
+
raise ERROR::HARDSPLOIT_NOT_FOUND
|
111
|
+
rescue
|
112
|
+
raise ERROR::USB_ERROR
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Wait to receive data
|
117
|
+
# * +timeout+:: timeout to read response (ms)
|
118
|
+
# Return USB_STATE or array with response (improve soon with exception)
|
119
|
+
def receiveDATA(timeout)
|
120
|
+
begin
|
121
|
+
received_data = @dev.bulk_transfer(:endpoint=>IN_ENDPOINT, :dataIn=>USB::USB_TRAME_SIZE, :timeout=>timeout)
|
122
|
+
return received_data
|
123
|
+
rescue LIBUSB::ERROR_NO_DEVICE
|
124
|
+
raise ERROR::USB_ERROR
|
125
|
+
rescue LIBUSB::ERROR_NO_DEVICE
|
126
|
+
raise ERROR::HARDSPLOIT_NOT_FOUND
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Send USB packet
|
131
|
+
# * +packet+:: array with bytes
|
132
|
+
# Return number of byte sent
|
133
|
+
def sendPacket(packet_send)
|
134
|
+
|
135
|
+
begin
|
136
|
+
if packet_send.size <= 8191 then
|
137
|
+
|
138
|
+
packet_send[0] = HardsploitAPI.lowByte(word:packet_send.size)
|
139
|
+
packet_send[1] = HardsploitAPI.highByte(word:packet_send.size)
|
140
|
+
|
141
|
+
#if a multiple of packet size add a value to explicit the end of trame
|
142
|
+
if packet_send.size % 64 ==0 then
|
143
|
+
packet_send.push 0
|
144
|
+
end
|
145
|
+
|
146
|
+
number_of_data_send = 0
|
147
|
+
time = Benchmark.realtime do
|
148
|
+
number_of_data_send = @dev.bulk_transfer(:endpoint=>OUT_ENDPOINT, :dataOut=>packet_send.pack('c*'),:timeout=>3000)
|
149
|
+
end
|
150
|
+
consoleSpeed "SEND #{((number_of_data_send/time)).round(2)}Bytes/s SEND #{(number_of_data_send)}Bytes in #{time.round(4)} s"
|
151
|
+
if number_of_data_send == packet_send.size then
|
152
|
+
return number_of_data_send
|
153
|
+
else
|
154
|
+
raise ERROR::USB_ERROR
|
155
|
+
end
|
156
|
+
else
|
157
|
+
raise ERROR::USB_ERROR
|
158
|
+
end
|
159
|
+
rescue LIBUSB::ERROR_NO_DEVICE
|
160
|
+
#TRY TO RECONNECT maybe error due to disconnecting and reconnecting board
|
161
|
+
reconncet
|
162
|
+
rescue
|
163
|
+
raise ERROR::USB_ERROR
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -1,356 +1,356 @@
|
|
1
|
-
#===================================================
|
2
|
-
# Hardsploit API - By Opale Security
|
3
|
-
# www.opale-security.com || www.hardsploit.io
|
4
|
-
# License: GNU General Public License v3
|
5
|
-
# License URI: http://www.gnu.org/licenses/gpl.txt
|
6
|
-
#===================================================
|
7
|
-
require_relative '../../Core/HardsploitAPI'
|
8
|
-
class HardsploitAPI_I2C
|
9
|
-
|
10
|
-
public
|
11
|
-
|
12
|
-
#attr_accessor :speed
|
13
|
-
#attr_reader :device_version
|
14
|
-
|
15
|
-
# * +speed+:: I2C::KHZ_40 , I2C::KHZ_100 , I2C::KHZ_400 , I2C::KHZ_1000
|
16
|
-
def initialize(speed:)
|
17
|
-
#to be sure the singleton was initialize
|
18
|
-
HardsploitAPI.instance.connect
|
19
|
-
self.speed=speed
|
20
|
-
end
|
21
|
-
|
22
|
-
def speed
|
23
|
-
return @speed
|
24
|
-
end
|
25
|
-
|
26
|
-
def speed=(speed)
|
27
|
-
unless [HardsploitAPI::I2C::KHZ_40, HardsploitAPI::I2C::KHZ_100, HardsploitAPI::I2C::KHZ_400,HardsploitAPI::I2C::KHZ_1000].include?(speed) then
|
28
|
-
raise HardsploitAPI::ERROR::I2CWrongSpeed
|
29
|
-
end
|
30
|
-
@speed = speed
|
31
|
-
end
|
32
|
-
|
33
|
-
# Interact with I2C bus
|
34
|
-
# * +payload+:: payload to send
|
35
|
-
def i2c_Interact(payload:)
|
36
|
-
if (payload.size > 4000) then
|
37
|
-
raise TypeError, 'Size of the data need to be less than 4000'
|
38
|
-
end
|
39
|
-
|
40
|
-
packet = Array.new
|
41
|
-
packet.push 0 #low byte of lenght of trame refresh automaticly before send by usb
|
42
|
-
packet.push 0 #high byte of lenght of trame refresh automaticly before send by usb
|
43
|
-
packet.push HardsploitAPI.lowByte(word:HardsploitAPI::USB_COMMAND::FPGA_COMMAND)
|
44
|
-
packet.push HardsploitAPI.highByte(word:HardsploitAPI::USB_COMMAND::FPGA_COMMAND)
|
45
|
-
|
46
|
-
packet.push 0x50 #Command RAW COMMUNICATION TO FPGA FIFO
|
47
|
-
|
48
|
-
packet.push @speed #Add speed
|
49
|
-
packet.concat payload #Add data
|
50
|
-
|
51
|
-
#remove header (4 bytes 2 for size 2 for type of command)
|
52
|
-
return HardsploitAPI.instance.sendAndReceiveDATA(packet,2000).drop(4)
|
53
|
-
end
|
54
|
-
|
55
|
-
# Start I2C scan to find addresses
|
56
|
-
# * +speed+:: I2C::KHZ_100 , I2C::KHZ_400 , I2C::KHZ_1000
|
57
|
-
# * Return An array 256 value for each addresse if 0 not present if 1 present
|
58
|
-
def i2c_Scan
|
59
|
-
if (@speed < 0) and (@speed >3) then
|
60
|
-
I2CWrongSpeed
|
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(word:1) #Count Low Byte
|
70
|
-
array_i2c_scan.push HardsploitAPI.highByte(word:1) #Count High Byte
|
71
|
-
array_i2c_scan.push i
|
72
|
-
end
|
73
|
-
|
74
|
-
result_scan = i2c_Interact(payload:array_i2c_scan)
|
75
|
-
if result_scan.size != 256 then
|
76
|
-
result_scan.clear
|
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 (i2cBaseAddress:,startAddress:,stopAddress:,sizeMax:)
|
99
|
-
if ((startAddress < 0) or (startAddress > sizeMax-1)) then
|
100
|
-
raise TypeError, "Start address can't be negative and not more than size max - 1"
|
101
|
-
end
|
102
|
-
|
103
|
-
if ((stopAddress < 0) or (stopAddress > (sizeMax-1))) then
|
104
|
-
raise TypeError, "Stop address can't be negative and not more than size max-1 because start at 0"
|
105
|
-
end
|
106
|
-
|
107
|
-
if (stopAddress <= startAddress) then
|
108
|
-
raise TypeError, "Stop address need to be greater than start address"
|
109
|
-
end
|
110
|
-
|
111
|
-
numberOfByteAddress = (((Math.log(sizeMax-1,2)).floor + 1) / 8.0).ceil
|
112
|
-
if numberOfByteAddress > 4 then
|
113
|
-
raise TypeError, "Size max must be less than 2^32 about 4Gb"
|
114
|
-
end
|
115
|
-
|
116
|
-
if numberOfByteAddress <= 0 then
|
117
|
-
raise TypeError, "There is an issue with calculating of number of byte needed"
|
118
|
-
end
|
119
|
-
startTime = Time.now
|
120
|
-
packet_size = 2000 - numberOfByteAddress - 1
|
121
|
-
number_complet_packet = ( (stopAddress-startAddress+1) / packet_size).floor
|
122
|
-
size_last_packet = (stopAddress-startAddress+1) % packet_size
|
123
|
-
|
124
|
-
#SEND the first complete trame
|
125
|
-
for i in 0..number_complet_packet - 1 do
|
126
|
-
packet = generate_i2c_read_command(
|
127
|
-
i2cBaseAddress: i2cBaseAddress,
|
128
|
-
numberOfByteAddress: numberOfByteAddress + startAddress,
|
129
|
-
startAddress: i * packet_size,
|
130
|
-
size: packet_size
|
131
|
-
)
|
132
|
-
#Remove header, result of read command and numberOfByte Address too
|
133
|
-
HardsploitAPI.instance.consoleData ( process_dump_i2c_result( i2c_Interact( payload: packet )))
|
134
|
-
HardsploitAPI.instance.consoleProgress(
|
135
|
-
percent: 100 * ( i + 1 ) / ( number_complet_packet + ( size_last_packet.zero? ? 0 : 1 )),
|
136
|
-
startTime: startTime,
|
137
|
-
endTime: Time.new
|
138
|
-
)
|
139
|
-
end
|
140
|
-
|
141
|
-
if(size_last_packet > 0 ) then
|
142
|
-
packet = generate_i2c_read_command(
|
143
|
-
i2cBaseAddress: i2cBaseAddress,
|
144
|
-
numberOfByteAddress: numberOfByteAddress,
|
145
|
-
startAddress: number_complet_packet * packet_size + startAddress,
|
146
|
-
size: size_last_packet
|
147
|
-
)
|
148
|
-
#Remove header, result of read command and numberOfByte Address too
|
149
|
-
HardsploitAPI.instance.consoleData( process_dump_i2c_result( i2c_Interact( payload:packet )))
|
150
|
-
HardsploitAPI.instance.consoleProgress(
|
151
|
-
percent: 100,
|
152
|
-
startTime: startTime,
|
153
|
-
endTime: Time.new
|
154
|
-
)
|
155
|
-
end
|
156
|
-
|
157
|
-
delta = Time.now - startTime
|
158
|
-
HardsploitAPI.instance.consoleSpeed "Write in #{delta.round(4)} sec"
|
159
|
-
end
|
160
|
-
|
161
|
-
#For the moment only with EEPROM (not need to erase or activate write)
|
162
|
-
def i2c_Generic_Import (i2cBaseAddress:,startAddress:,pageSize:,memorySize:,dataFile:,writePageLatency:)
|
163
|
-
startTime = Time.now
|
164
|
-
begin
|
165
|
-
file = File.open(dataFile, 'rb')
|
166
|
-
sizeFile = file.size
|
167
|
-
rescue Exception => e
|
168
|
-
raise Error::FileIssue, e.message
|
169
|
-
end
|
170
|
-
|
171
|
-
if ((startAddress < 0) or (startAddress > memorySize - 1)) then
|
172
|
-
raise Error::WrongStartAddress
|
173
|
-
end
|
174
|
-
|
175
|
-
if ((pageSize <= 0) and (pageSize > 1024)) then
|
176
|
-
raise TypeError, "pageSize need to be greater than 0 and less than 1024"
|
177
|
-
end
|
178
|
-
|
179
|
-
numberOfByteAddress = (((Math.log(memorySize - 1, 2)).floor + 1) / 8.0).ceil
|
180
|
-
if numberOfByteAddress > 4 then
|
181
|
-
raise TypeError, "Size max must be less than 2^32 about 4Gb"
|
182
|
-
end
|
183
|
-
|
184
|
-
if numberOfByteAddress <= 0 then
|
185
|
-
raise TypeError, "There is an issue with calculating of number of byte needed"
|
186
|
-
end
|
187
|
-
|
188
|
-
packet_size = pageSize
|
189
|
-
number_complet_packet = (sizeFile / packet_size).floor
|
190
|
-
size_last_packet = sizeFile % packet_size
|
191
|
-
|
192
|
-
#SEND the first complete trame
|
193
|
-
for i in 0..number_complet_packet-1 do
|
194
|
-
packet = generate_i2c_write_command(
|
195
|
-
i2cBaseAddress: i2cBaseAddress,
|
196
|
-
numberOfByteAddress: numberOfByteAddress,
|
197
|
-
startAddress: i * packet_size,
|
198
|
-
data: file.read( packet_size ).unpack( "C*" )
|
199
|
-
)
|
200
|
-
|
201
|
-
#Remove header, result of read command and numberOfByte Address too
|
202
|
-
process_import_i2c_result( i2c_Interact( payload: packet ))
|
203
|
-
|
204
|
-
HardsploitAPI.instance.consoleProgress(
|
205
|
-
percent: 100 * ( i + 1 ) / ( number_complet_packet + ( size_last_packet.zero? ? 0 : 1 )),
|
206
|
-
startTime: startTime,
|
207
|
-
endTime: Time.new
|
208
|
-
)
|
209
|
-
#if too many error when write increase because we need to wait to write a full page
|
210
|
-
sleep(writePageLatency)
|
211
|
-
end
|
212
|
-
|
213
|
-
if(size_last_packet > 0 ) then
|
214
|
-
packet = generate_i2c_write_command(
|
215
|
-
i2cBaseAddress: i2cBaseAddress,
|
216
|
-
numberOfByteAddress: numberOfByteAddress,
|
217
|
-
startAddress: number_complet_packet * packet_size + startAddress,
|
218
|
-
data: file.read( size_last_packet ).unpack( "C*" )
|
219
|
-
)
|
220
|
-
|
221
|
-
#Remove header, result of read command and numberOfByte Address too
|
222
|
-
process_import_i2c_result ( i2c_Interact(payload: packet) )
|
223
|
-
HardsploitAPI.instance.consoleProgress(
|
224
|
-
percent: 100,
|
225
|
-
startTime: startTime,
|
226
|
-
endTime: Time.new
|
227
|
-
)
|
228
|
-
end
|
229
|
-
|
230
|
-
delta = Time.now - startTime
|
231
|
-
HardsploitAPI.instance.consoleSpeed "Write in #{delta.round(4)} sec"
|
232
|
-
end
|
233
|
-
|
234
|
-
def find(numberOfConnectedPinFromA0:)
|
235
|
-
posibility = HardsploitAPI.allPosibility(
|
236
|
-
numberOfConnectedPinFromA0: numberOfConnectedPinFromA0,
|
237
|
-
numberOfSignalsForBus: 2
|
238
|
-
)
|
239
|
-
compare_tab = Array.new(256, 1)
|
240
|
-
for item in posibility
|
241
|
-
currentWiring = 0
|
242
|
-
for value in item
|
243
|
-
currentWiring += 2 ** value
|
244
|
-
end
|
245
|
-
HardsploitAPI.instance.setWiringLeds(value: currentWiring)
|
246
|
-
for i in 0..(63 - item.size)
|
247
|
-
item.push i + numberOfConnectedPinFromA0
|
248
|
-
end
|
249
|
-
HardsploitAPI.instance.setCrossWiring(value: item)
|
250
|
-
begin
|
251
|
-
tab = i2c_Scan
|
252
|
-
return item if tab.include?(1) and tab != compare_tab
|
253
|
-
rescue Exception => msg
|
254
|
-
puts msg
|
255
|
-
end
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
259
|
-
private
|
260
|
-
|
261
|
-
def process_import_i2c_result (packet)
|
262
|
-
result = Array.new
|
263
|
-
for i in (0..packet.size - 1).step(2) do
|
264
|
-
case packet[i]
|
265
|
-
when 0 #Write ACK
|
266
|
-
#Do nothing,don't save write ack
|
267
|
-
else
|
268
|
-
raise TypeError, "Error in I2C transaction (NACK), write failed "
|
269
|
-
end
|
270
|
-
end
|
271
|
-
return result
|
272
|
-
end
|
273
|
-
|
274
|
-
def process_dump_i2c_result (packet)
|
275
|
-
result = Array.new
|
276
|
-
for i in (0..packet.size - 1).step(2) do
|
277
|
-
case packet[i]
|
278
|
-
when 1 #Read ACK
|
279
|
-
#Save read data
|
280
|
-
result.push packet[i + 1]
|
281
|
-
when 0 #Write ACK
|
282
|
-
#Do nothing,don't save write ack
|
283
|
-
else
|
284
|
-
raise TypeError, "Error in I2C transaction, I2C export seems to be wrong"
|
285
|
-
end
|
286
|
-
end
|
287
|
-
return result
|
288
|
-
end
|
289
|
-
|
290
|
-
def generate_i2c_write_command (i2cBaseAddress:, numberOfByteAddress:, startAddress:, data:)
|
291
|
-
packet = Array.new
|
292
|
-
#Push write command
|
293
|
-
packet.push HardsploitAPI.lowByte(word:numberOfByteAddress+data.size) #size of write command
|
294
|
-
packet.push HardsploitAPI.highByte(word:numberOfByteAddress+data.size) #size of write command
|
295
|
-
|
296
|
-
packet.push i2cBaseAddress #push Write address
|
297
|
-
|
298
|
-
case numberOfByteAddress
|
299
|
-
when 1
|
300
|
-
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
301
|
-
when 2
|
302
|
-
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
303
|
-
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart
|
304
|
-
when 3
|
305
|
-
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
306
|
-
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
307
|
-
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
308
|
-
when 4
|
309
|
-
packet.push ((startAddress & 0xFF000000) >> 24 ) #AddStart3
|
310
|
-
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
311
|
-
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
312
|
-
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
313
|
-
else
|
314
|
-
raise TypeError, "Issue in generate_i2c_write_command function when parse number of byte address"
|
315
|
-
end
|
316
|
-
|
317
|
-
#Push data to write
|
318
|
-
packet.push *data
|
319
|
-
return packet
|
320
|
-
end
|
321
|
-
|
322
|
-
def generate_i2c_read_command (i2cBaseAddress:, numberOfByteAddress:, startAddress:, size:)
|
323
|
-
packet = Array.new
|
324
|
-
#Push write command for start address
|
325
|
-
packet.push HardsploitAPI.lowByte(word: numberOfByteAddress) #size of write command
|
326
|
-
packet.push HardsploitAPI.highByte(word: numberOfByteAddress) #size of write command
|
327
|
-
|
328
|
-
packet.push i2cBaseAddress #push Write address
|
329
|
-
|
330
|
-
case numberOfByteAddress
|
331
|
-
when 1
|
332
|
-
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
333
|
-
when 2
|
334
|
-
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
335
|
-
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart
|
336
|
-
when 3
|
337
|
-
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
338
|
-
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
339
|
-
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
340
|
-
when 4
|
341
|
-
packet.push ((startAddress & 0xFF000000) >> 24 ) #AddStart3
|
342
|
-
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
343
|
-
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
344
|
-
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
345
|
-
else
|
346
|
-
raise TypeError, "Issue in generate_spi_read_command function when parse number of byte address"
|
347
|
-
end
|
348
|
-
|
349
|
-
#Push read command to read size data
|
350
|
-
packet.push HardsploitAPI.lowByte(word:size) #size of read command
|
351
|
-
packet.push HardsploitAPI.highByte(word:size) #size of read command
|
352
|
-
packet.push i2cBaseAddress+1 #push read address
|
353
|
-
|
354
|
-
return packet
|
355
|
-
end
|
356
|
-
end
|
1
|
+
#===================================================
|
2
|
+
# Hardsploit API - By Opale Security
|
3
|
+
# www.opale-security.com || www.hardsploit.io
|
4
|
+
# License: GNU General Public License v3
|
5
|
+
# License URI: http://www.gnu.org/licenses/gpl.txt
|
6
|
+
#===================================================
|
7
|
+
require_relative '../../Core/HardsploitAPI'
|
8
|
+
class HardsploitAPI_I2C
|
9
|
+
|
10
|
+
public
|
11
|
+
|
12
|
+
#attr_accessor :speed
|
13
|
+
#attr_reader :device_version
|
14
|
+
|
15
|
+
# * +speed+:: I2C::KHZ_40 , I2C::KHZ_100 , I2C::KHZ_400 , I2C::KHZ_1000
|
16
|
+
def initialize(speed:)
|
17
|
+
#to be sure the singleton was initialize
|
18
|
+
HardsploitAPI.instance.connect
|
19
|
+
self.speed=speed
|
20
|
+
end
|
21
|
+
|
22
|
+
def speed
|
23
|
+
return @speed
|
24
|
+
end
|
25
|
+
|
26
|
+
def speed=(speed)
|
27
|
+
unless [HardsploitAPI::I2C::KHZ_40, HardsploitAPI::I2C::KHZ_100, HardsploitAPI::I2C::KHZ_400,HardsploitAPI::I2C::KHZ_1000].include?(speed) then
|
28
|
+
raise HardsploitAPI::ERROR::I2CWrongSpeed
|
29
|
+
end
|
30
|
+
@speed = speed
|
31
|
+
end
|
32
|
+
|
33
|
+
# Interact with I2C bus
|
34
|
+
# * +payload+:: payload to send
|
35
|
+
def i2c_Interact(payload:)
|
36
|
+
if (payload.size > 4000) then
|
37
|
+
raise TypeError, 'Size of the data need to be less than 4000'
|
38
|
+
end
|
39
|
+
|
40
|
+
packet = Array.new
|
41
|
+
packet.push 0 #low byte of lenght of trame refresh automaticly before send by usb
|
42
|
+
packet.push 0 #high byte of lenght of trame refresh automaticly before send by usb
|
43
|
+
packet.push HardsploitAPI.lowByte(word:HardsploitAPI::USB_COMMAND::FPGA_COMMAND)
|
44
|
+
packet.push HardsploitAPI.highByte(word:HardsploitAPI::USB_COMMAND::FPGA_COMMAND)
|
45
|
+
|
46
|
+
packet.push 0x50 #Command RAW COMMUNICATION TO FPGA FIFO
|
47
|
+
|
48
|
+
packet.push @speed #Add speed
|
49
|
+
packet.concat payload #Add data
|
50
|
+
|
51
|
+
#remove header (4 bytes 2 for size 2 for type of command)
|
52
|
+
return HardsploitAPI.instance.sendAndReceiveDATA(packet,2000).drop(4)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Start I2C scan to find addresses
|
56
|
+
# * +speed+:: I2C::KHZ_100 , I2C::KHZ_400 , I2C::KHZ_1000
|
57
|
+
# * Return An array 256 value for each addresse if 0 not present if 1 present
|
58
|
+
def i2c_Scan
|
59
|
+
if (@speed < 0) and (@speed >3) then
|
60
|
+
I2CWrongSpeed
|
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(word:1) #Count Low Byte
|
70
|
+
array_i2c_scan.push HardsploitAPI.highByte(word:1) #Count High Byte
|
71
|
+
array_i2c_scan.push i
|
72
|
+
end
|
73
|
+
|
74
|
+
result_scan = i2c_Interact(payload:array_i2c_scan)
|
75
|
+
if result_scan.size != 256 then
|
76
|
+
result_scan.clear
|
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 (i2cBaseAddress:,startAddress:,stopAddress:,sizeMax:)
|
99
|
+
if ((startAddress < 0) or (startAddress > sizeMax-1)) then
|
100
|
+
raise TypeError, "Start address can't be negative and not more than size max - 1"
|
101
|
+
end
|
102
|
+
|
103
|
+
if ((stopAddress < 0) or (stopAddress > (sizeMax-1))) then
|
104
|
+
raise TypeError, "Stop address can't be negative and not more than size max-1 because start at 0"
|
105
|
+
end
|
106
|
+
|
107
|
+
if (stopAddress <= startAddress) then
|
108
|
+
raise TypeError, "Stop address need to be greater than start address"
|
109
|
+
end
|
110
|
+
|
111
|
+
numberOfByteAddress = (((Math.log(sizeMax-1,2)).floor + 1) / 8.0).ceil
|
112
|
+
if numberOfByteAddress > 4 then
|
113
|
+
raise TypeError, "Size max must be less than 2^32 about 4Gb"
|
114
|
+
end
|
115
|
+
|
116
|
+
if numberOfByteAddress <= 0 then
|
117
|
+
raise TypeError, "There is an issue with calculating of number of byte needed"
|
118
|
+
end
|
119
|
+
startTime = Time.now
|
120
|
+
packet_size = 2000 - numberOfByteAddress - 1
|
121
|
+
number_complet_packet = ( (stopAddress-startAddress+1) / packet_size).floor
|
122
|
+
size_last_packet = (stopAddress-startAddress+1) % packet_size
|
123
|
+
|
124
|
+
#SEND the first complete trame
|
125
|
+
for i in 0..number_complet_packet - 1 do
|
126
|
+
packet = generate_i2c_read_command(
|
127
|
+
i2cBaseAddress: i2cBaseAddress,
|
128
|
+
numberOfByteAddress: numberOfByteAddress + startAddress,
|
129
|
+
startAddress: i * packet_size,
|
130
|
+
size: packet_size
|
131
|
+
)
|
132
|
+
#Remove header, result of read command and numberOfByte Address too
|
133
|
+
HardsploitAPI.instance.consoleData ( process_dump_i2c_result( i2c_Interact( payload: packet )))
|
134
|
+
HardsploitAPI.instance.consoleProgress(
|
135
|
+
percent: 100 * ( i + 1 ) / ( number_complet_packet + ( size_last_packet.zero? ? 0 : 1 )),
|
136
|
+
startTime: startTime,
|
137
|
+
endTime: Time.new
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
141
|
+
if(size_last_packet > 0 ) then
|
142
|
+
packet = generate_i2c_read_command(
|
143
|
+
i2cBaseAddress: i2cBaseAddress,
|
144
|
+
numberOfByteAddress: numberOfByteAddress,
|
145
|
+
startAddress: number_complet_packet * packet_size + startAddress,
|
146
|
+
size: size_last_packet
|
147
|
+
)
|
148
|
+
#Remove header, result of read command and numberOfByte Address too
|
149
|
+
HardsploitAPI.instance.consoleData( process_dump_i2c_result( i2c_Interact( payload:packet )))
|
150
|
+
HardsploitAPI.instance.consoleProgress(
|
151
|
+
percent: 100,
|
152
|
+
startTime: startTime,
|
153
|
+
endTime: Time.new
|
154
|
+
)
|
155
|
+
end
|
156
|
+
|
157
|
+
delta = Time.now - startTime
|
158
|
+
HardsploitAPI.instance.consoleSpeed "Write in #{delta.round(4)} sec"
|
159
|
+
end
|
160
|
+
|
161
|
+
#For the moment only with EEPROM (not need to erase or activate write)
|
162
|
+
def i2c_Generic_Import (i2cBaseAddress:,startAddress:,pageSize:,memorySize:,dataFile:,writePageLatency:)
|
163
|
+
startTime = Time.now
|
164
|
+
begin
|
165
|
+
file = File.open(dataFile, 'rb')
|
166
|
+
sizeFile = file.size
|
167
|
+
rescue Exception => e
|
168
|
+
raise Error::FileIssue, e.message
|
169
|
+
end
|
170
|
+
|
171
|
+
if ((startAddress < 0) or (startAddress > memorySize - 1)) then
|
172
|
+
raise Error::WrongStartAddress
|
173
|
+
end
|
174
|
+
|
175
|
+
if ((pageSize <= 0) and (pageSize > 1024)) then
|
176
|
+
raise TypeError, "pageSize need to be greater than 0 and less than 1024"
|
177
|
+
end
|
178
|
+
|
179
|
+
numberOfByteAddress = (((Math.log(memorySize - 1, 2)).floor + 1) / 8.0).ceil
|
180
|
+
if numberOfByteAddress > 4 then
|
181
|
+
raise TypeError, "Size max must be less than 2^32 about 4Gb"
|
182
|
+
end
|
183
|
+
|
184
|
+
if numberOfByteAddress <= 0 then
|
185
|
+
raise TypeError, "There is an issue with calculating of number of byte needed"
|
186
|
+
end
|
187
|
+
|
188
|
+
packet_size = pageSize
|
189
|
+
number_complet_packet = (sizeFile / packet_size).floor
|
190
|
+
size_last_packet = sizeFile % packet_size
|
191
|
+
|
192
|
+
#SEND the first complete trame
|
193
|
+
for i in 0..number_complet_packet-1 do
|
194
|
+
packet = generate_i2c_write_command(
|
195
|
+
i2cBaseAddress: i2cBaseAddress,
|
196
|
+
numberOfByteAddress: numberOfByteAddress,
|
197
|
+
startAddress: i * packet_size,
|
198
|
+
data: file.read( packet_size ).unpack( "C*" )
|
199
|
+
)
|
200
|
+
|
201
|
+
#Remove header, result of read command and numberOfByte Address too
|
202
|
+
process_import_i2c_result( i2c_Interact( payload: packet ))
|
203
|
+
|
204
|
+
HardsploitAPI.instance.consoleProgress(
|
205
|
+
percent: 100 * ( i + 1 ) / ( number_complet_packet + ( size_last_packet.zero? ? 0 : 1 )),
|
206
|
+
startTime: startTime,
|
207
|
+
endTime: Time.new
|
208
|
+
)
|
209
|
+
#if too many error when write increase because we need to wait to write a full page
|
210
|
+
sleep(writePageLatency)
|
211
|
+
end
|
212
|
+
|
213
|
+
if(size_last_packet > 0 ) then
|
214
|
+
packet = generate_i2c_write_command(
|
215
|
+
i2cBaseAddress: i2cBaseAddress,
|
216
|
+
numberOfByteAddress: numberOfByteAddress,
|
217
|
+
startAddress: number_complet_packet * packet_size + startAddress,
|
218
|
+
data: file.read( size_last_packet ).unpack( "C*" )
|
219
|
+
)
|
220
|
+
|
221
|
+
#Remove header, result of read command and numberOfByte Address too
|
222
|
+
process_import_i2c_result ( i2c_Interact(payload: packet) )
|
223
|
+
HardsploitAPI.instance.consoleProgress(
|
224
|
+
percent: 100,
|
225
|
+
startTime: startTime,
|
226
|
+
endTime: Time.new
|
227
|
+
)
|
228
|
+
end
|
229
|
+
|
230
|
+
delta = Time.now - startTime
|
231
|
+
HardsploitAPI.instance.consoleSpeed "Write in #{delta.round(4)} sec"
|
232
|
+
end
|
233
|
+
|
234
|
+
def find(numberOfConnectedPinFromA0:)
|
235
|
+
posibility = HardsploitAPI.allPosibility(
|
236
|
+
numberOfConnectedPinFromA0: numberOfConnectedPinFromA0,
|
237
|
+
numberOfSignalsForBus: 2
|
238
|
+
)
|
239
|
+
compare_tab = Array.new(256, 1)
|
240
|
+
for item in posibility
|
241
|
+
currentWiring = 0
|
242
|
+
for value in item
|
243
|
+
currentWiring += 2 ** value
|
244
|
+
end
|
245
|
+
HardsploitAPI.instance.setWiringLeds(value: currentWiring)
|
246
|
+
for i in 0..(63 - item.size)
|
247
|
+
item.push i + numberOfConnectedPinFromA0
|
248
|
+
end
|
249
|
+
HardsploitAPI.instance.setCrossWiring(value: item)
|
250
|
+
begin
|
251
|
+
tab = i2c_Scan
|
252
|
+
return item if tab.include?(1) and tab != compare_tab
|
253
|
+
rescue Exception => msg
|
254
|
+
puts msg
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
private
|
260
|
+
|
261
|
+
def process_import_i2c_result (packet)
|
262
|
+
result = Array.new
|
263
|
+
for i in (0..packet.size - 1).step(2) do
|
264
|
+
case packet[i]
|
265
|
+
when 0 #Write ACK
|
266
|
+
#Do nothing,don't save write ack
|
267
|
+
else
|
268
|
+
raise TypeError, "Error in I2C transaction (NACK), write failed "
|
269
|
+
end
|
270
|
+
end
|
271
|
+
return result
|
272
|
+
end
|
273
|
+
|
274
|
+
def process_dump_i2c_result (packet)
|
275
|
+
result = Array.new
|
276
|
+
for i in (0..packet.size - 1).step(2) do
|
277
|
+
case packet[i]
|
278
|
+
when 1 #Read ACK
|
279
|
+
#Save read data
|
280
|
+
result.push packet[i + 1]
|
281
|
+
when 0 #Write ACK
|
282
|
+
#Do nothing,don't save write ack
|
283
|
+
else
|
284
|
+
raise TypeError, "Error in I2C transaction, I2C export seems to be wrong"
|
285
|
+
end
|
286
|
+
end
|
287
|
+
return result
|
288
|
+
end
|
289
|
+
|
290
|
+
def generate_i2c_write_command (i2cBaseAddress:, numberOfByteAddress:, startAddress:, data:)
|
291
|
+
packet = Array.new
|
292
|
+
#Push write command
|
293
|
+
packet.push HardsploitAPI.lowByte(word:numberOfByteAddress+data.size) #size of write command
|
294
|
+
packet.push HardsploitAPI.highByte(word:numberOfByteAddress+data.size) #size of write command
|
295
|
+
|
296
|
+
packet.push i2cBaseAddress #push Write address
|
297
|
+
|
298
|
+
case numberOfByteAddress
|
299
|
+
when 1
|
300
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
301
|
+
when 2
|
302
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
303
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart
|
304
|
+
when 3
|
305
|
+
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
306
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
307
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
308
|
+
when 4
|
309
|
+
packet.push ((startAddress & 0xFF000000) >> 24 ) #AddStart3
|
310
|
+
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
311
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
312
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
313
|
+
else
|
314
|
+
raise TypeError, "Issue in generate_i2c_write_command function when parse number of byte address"
|
315
|
+
end
|
316
|
+
|
317
|
+
#Push data to write
|
318
|
+
packet.push *data
|
319
|
+
return packet
|
320
|
+
end
|
321
|
+
|
322
|
+
def generate_i2c_read_command (i2cBaseAddress:, numberOfByteAddress:, startAddress:, size:)
|
323
|
+
packet = Array.new
|
324
|
+
#Push write command for start address
|
325
|
+
packet.push HardsploitAPI.lowByte(word: numberOfByteAddress) #size of write command
|
326
|
+
packet.push HardsploitAPI.highByte(word: numberOfByteAddress) #size of write command
|
327
|
+
|
328
|
+
packet.push i2cBaseAddress #push Write address
|
329
|
+
|
330
|
+
case numberOfByteAddress
|
331
|
+
when 1
|
332
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
333
|
+
when 2
|
334
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
335
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart
|
336
|
+
when 3
|
337
|
+
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
338
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
339
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
340
|
+
when 4
|
341
|
+
packet.push ((startAddress & 0xFF000000) >> 24 ) #AddStart3
|
342
|
+
packet.push ((startAddress & 0x00FF0000) >> 16 ) #AddStart2
|
343
|
+
packet.push ((startAddress & 0x0000FF00) >> 8 ) #AddStart1
|
344
|
+
packet.push ((startAddress & 0x000000FF) >> 0) #AddStart0
|
345
|
+
else
|
346
|
+
raise TypeError, "Issue in generate_spi_read_command function when parse number of byte address"
|
347
|
+
end
|
348
|
+
|
349
|
+
#Push read command to read size data
|
350
|
+
packet.push HardsploitAPI.lowByte(word:size) #size of read command
|
351
|
+
packet.push HardsploitAPI.highByte(word:size) #size of read command
|
352
|
+
packet.push i2cBaseAddress+1 #push read address
|
353
|
+
|
354
|
+
return packet
|
355
|
+
end
|
356
|
+
end
|