How to determine the the semantic of the ACPI "control methods"? - firmware

I am new to the ACPI technology. So far, I understand that ACPI defines some control methods which can be used to manipulate the devices on motherboard.
I tried the acpiexec.exe from the ACPICA. And dumped many control methods as below:
\_SB.PCI0.EHC1._STA Method 77f351d0 01 Args 0 Len 000F Aml 78aa8b77
\_SB.PCI0.EHC1._RMV Method 77f35290 01 Args 0 Len 0002 Aml 78aa8b8d
\_SB.PCI0.EHC1._PR3 Method 77f352d0 01 Args 0 Len 0008 Aml 78aa8b96
\_SB.PCI0.SBUS.SSXB Method 77f34cd0 01 Args 2 Len 00A4 Aml 78aa8bd2
\_SB.PCI0.SBUS.SRXB Method 77f34d90 01 Args 1 Len 00A8 Aml 78aa8c7e
\_SB.PCI0.SBUS.SWRB Method 77f34c90 01 Args 3 Len 00AA Aml 78aa8d2e
\_SB.PCI0.SBUS.SRDB Method 77f34bd0 01 Args 2 Len 00AE Aml 78aa8de0
\_SB.PCI0.SBUS.SWRW Method 77f34dd0 01 Args 3 Len 00B8 Aml 78aa8e96
\_SB.PCI0.SBUS.SRDW Method 77f34b90 01 Args 2 Len 00BA Aml 78aa8f56
\_SB.PCI0.SBUS.SBLW Method 77f348d0 01 Args 4 Len 00FA Aml 78aa9018
\_SB.PCI0.SBUS.SBLR Method 77f346d0 01 Args 3 Len 0130 Aml 78aa911a
\_SB.PCI0.SBUS.STRT Method 77f34710 01 Args 0 Len 00AF Aml 78aa9252
But I don't know the semantic of each method, such as:
What args they require?
What action do they carry out?
I searched the ACPI 6.0 sepc. But seems there's not a comprehensive list of all control methods as I expected. Anyone could shed some light? Thanks.
ADD 1
Seems the ACPI 6.0 spec does cover some. I will search in it for now.

Related

Defining variables in asm

Is the following a valid way to define variables in asm?
.globl main
.globl a, b, c, d
a: .byte 4
b: .value 7
c: .long 0x0C # 11
d: .quad 9
main:
mov $0, %eax
add a(%rip), %eax
add b(%rip), %eax
add c(%rip), %eax
add d(%rip), %eax
ret
For example, is it required/suggested to have a .TEXT section? How exactly does a(%rip) resolve to the value of $4? That seems almost like magic to me.
The default section is .text; lines before any section directive assemble into the .text section. So you do have one, and in fact you put everything in it, including your data. (Or read-only constants.) Normally you should put static constants in .rodata (or .rdata on Windows), not in .text, for performance reasons. (Mixing code and data wastes space in the I-cache and D-cache, and in TLBs.)
It doesn't resolve to an immediate $4 at assemble time, it resolves to an address. In this case, using a RIP-relative addressing mode. See what does "mov offset(%rip), %rax" do? / How do RIP-relative variable references like "[RIP + _a]" in x86-64 GAS Intel-syntax work? for more about the fact that it means "address of symbol a with respect to RIP", not actually RIP + absolute address of the symbol.
In other cases, the symbol a does generally resolve to its (32-bit) absolute address when used as add $a, %rdi or something.
It's only at runtime that the CPU loads data (which you put there with directives like .long) from that static storage. If you changed what was in memory (e.g. with a debugger, or by running other instructions) before add c(%rip), %eax executed, it would load a different value.
You put your constant data in .text, along with the code, which is generally not what you want for performance reasons. But it means the assembler can resolve the RIP-relative addressing at assemble time instead of only using a relocation that the linker has to fill in. Although it seems GAS chooses not to resolve the references and still leaves it for the linker:
$ gcc -c foo.s
$ objdump -drwC -Matt foo.o
foo.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <a>:
0: 04 .byte 0x4
0000000000000001 <b>:
1: 07 (bad)
...
0000000000000003 <c>:
3: 0c 00 or $0x0,%al
...
0000000000000007 <d>:
7: 09 00 or %eax,(%rax)
9: 00 00 add %al,(%rax)
b: 00 00 add %al,(%rax)
...
000000000000000f <main>:
f: b8 00 00 00 00 mov $0x0,%eax
14: 03 05 00 00 00 00 add 0x0(%rip),%eax # 1a <main+0xb> 16: R_X86_64_PC32 a-0x4
1a: 03 05 00 00 00 00 add 0x0(%rip),%eax # 20 <main+0x11> 1c: R_X86_64_PC32 b-0x4
20: 03 05 00 00 00 00 add 0x0(%rip),%eax # 26 <main+0x17> 22: R_X86_64_PC32 c-0x4
26: 03 05 00 00 00 00 add 0x0(%rip),%eax # 2c <main+0x1d> 28: R_X86_64_PC32 d-0x4
2c: c3 retq
(Attempted disassembly of your data as instructions happens because you put them in .text. objdump -d only disassembles .text, and non-immediate constants are normally placed in .rodata.)
Linking it into a executable resolves those symbol references:
$ gcc -nostdlib -static foo.s # not a working executable, just link it without extra stuff
$ objdump -drwC -Matt a.out
... (bogus data omitted)
000000000040100f <main>:
40100f: b8 00 00 00 00 mov $0x0,%eax
401014: 03 05 e6 ff ff ff add -0x1a(%rip),%eax # 401000 <a>
40101a: 03 05 e1 ff ff ff add -0x1f(%rip),%eax # 401001 <b>
401020: 03 05 dd ff ff ff add -0x23(%rip),%eax # 401003 <c>
401026: 03 05 db ff ff ff add -0x25(%rip),%eax # 401007 <d>
40102c: c3 retq
Note the 32-bit little-endian 2's complement encoding of the relative offsets in the RIP+rel32 addressing modes. (And the comment with the absolute address, added by objdump for convenience in this disassembly output.)
BTW, most assemblers including GAS have macro facilities, so you could have used a = 4 or .equ a, 4 to define it as an assemble-time constant, instead of emitting data into the output there. Then you'd use it as add $a, %eax, which would assemble to an add $sign_extended_imm8, r/m32 opcode.
Also, all your loads are dword sized (determined by the register operand), so only 1 of them matches the size of the data directives you used. Single-step through your code and look at the high bits of EAX.
Assembly language doesn't really have variables. It has tools you can use to implement the high-level-language concept of variables, including variables with static storage class. (A label and some space in .data or .bss. Or .rodata for const "variables".)
But if you use the tools differently, you can do things like load 4 bytes that span the .byte, the .value (16-bit), and the first byte of the .long. So after the first instruction, you'll have EAX += 0x0c000704 (because x86 is little-endian). This is totally legal to write in assembler, and nothing is checking to enforce the concept of a variable as ending before the next label.
(Unless you use MASM, which does have variables; in that case you'd have had to write add eax, dword ptr [a]; without the size override MASM would complain about the mismatch between a dword register and a byte variable. Other flavours of asm syntax, like NASM and AT&T, assume you know what you're doing and don't try to be "helpful".)

How to set and update ICC card PIN with APDU command

I have a contact smartcard.(I dont know about what kind of applet installed on it. But I can authenticate, read, update and verify pin with standart APDU commands.) And I want to do some changes on PIN.
So, my question is:
If card has PIN, then update the PIN with new value. If card dont have any PIN, then set PIN.
Standart update command is not working on PIN file. I am getting 6982 response message from ICC card. So, what is the approach to success above situation.
I searched on internet about it, But I didnt find any useful Docs&Articles.
Error 6982 stands for "Security condition not satisfied".
PINs are never transmitted plain as you have mentioned in your packet. They are always encrypted for the software involved between a User and the ICC can sneak peak the packet. A public key has to be obtained using GET_CHALLENGE command and used for enciphering of the PIN.
According EMV spec, the APDU for PIN change is
CLA = 8C or 84;
INS = 24
P1 = 00
P2 = 01/ 02
Lc = Number of data bytes
Data = Enciphered PIN data component, if present, and MAC data component;
CLA and Data are to be coded according to the secure messaging specified in EMV Book 2
P2 = 01 => PIN Data Generated Using the Current PIN
P2 = 02 => PIN Data Generated Without Using the Current PIN
new PIN is encapsulated in the Data field
Finaly I found solution, and I am putting the answer here.
Firstly, we need to select PIN FILE. For this
Select MF(Master File)
Select DF(Dedicated file)
Select PIN EF (Elementry file)
Select App Master File : 00 A4 00 00 02 XX XX
Select App Dedicated File : 00 A4 00 00 02 XX XX
Select App Pin File : 00 A4 00 00 02 XX XX
Change Pin coommand: 00 24 [TM] [KN] [LN] XX XX .. ..
TM: Transfer Mode (Clear Transfer) : 00 KN: Key Number: 10 LN:
Total Pin Length(Every time 16 bytes): 10
For example (Old pin is “1234” and we want to change pin to
“5678”:
Change Pin : 00 24 00 10 10 31 32 33 34 FF FF FF FF 35 36 37 38 FF
FF FF FF (FF: padding value)

modified elf symbol but not reflecting in disassembly

I have used a symbol "__copy_start" inside my assembly code which is coming from linker script. symbol is defined as ABS in symbol table.
This symbol is used inside a macro to copy data from one memory location to another.
After looking at varenter code hereious ways to modify this symbol directly in elf i decided to write C code of my own to modify the symbol value.
To do that i traversed entire symbol table and did string match for the symbol i am interested in. When there is a symbol name match i just assigned symbol_table.st_value = new value.
To make sure the new value is taken i did readelf -s and checked that it does show the new value assigned by me.
Now, when i disassemble the modified elf i find that the new value has not taken effect and i still see the assembly code doing copy from old symbol value.
My question is:
Am i doing something wrong here? is it possible to change the symbol values in elf? If yes, please let me know the correct way to do it. How do i achieve what i intend to do here.
Note: I don't have the source code so taking this approach.
Thanks in advance,
Gaurav
wanted to add more information so that people can understand better.
copying the elf header below:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
**Type: EXEC (Executable file)**
Machine: Ubicom32 32-bit microcontrollers
Version: 0x1
Entry point address: 0xb0000000
Start of program headers: 52 (bytes into file)
Start of section headers: 33548 (bytes into file)
Flags: 0x6
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 2
Size of section headers: 40 (bytes)
Number of section headers: 6
Section header string table index: 3
Here as you can see that file is of type executable.
output of readelf -S copied below:
There are 6 section headers, starting at offset 0x830c:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 3ffc0000 004000 000ebc 00 AX 0 0 1
[ 2] .sdram PROGBITS 50000000 008000 0002e4 00 WA 0 0 1
[ 3] .shstrtab STRTAB 00000000 0082e4 000028 00 0 0 1
[ 4] .symtab SYMTAB 00000000 0083fc 0001c0 10 5 20 4
[ 5] .strtab STRTAB 00000000 0085bc 00019a 00 0 0 1
I am using one of the symbol named "__copy_start" in an instruction to copy the data from .sdram section to .text section. I was under an impression that i could go and change the symbol_table.st_value and then get the desired work done. But unfortunately that is not the case. Seems like it is already compiled and cannot be changed like this.
Any idea how this could be done would be really helpful.
Regards,
Gaurav
Are you sure that the object code actually uses a relocation to reference the data at the __copy_start symbol? Even for position-independent code, it is usually possible to turn section start addresses into relative addresses, which do not need a relocation. (That the symbol itself remains present with an absolute address does not change this.)
You can check this by using readelf -r or eu-readelf -r and examining the output. It is also visible in the objdump --dissassemble --reloc output.

How to send APDU to Mifare Classic 1k card?

What I am trying to achieve is to send APDU command to MIFARE Classic 1K card to change its A and B keys.
I was able to establish a connection with the card and use a default key (FFFFFFFFFFFF) to read block 0 and block 1. I used HID MifareSamples application for it.
Now, I would like to change A key from default to something else. I found a solution here, at stackoverflow (Mifare Change KEY A and B) which suggests that I have to send this APDU:
New key A = 00 11 22 33 44 55 Access bits not overwritten Key B not
used (so FF FF FF FF FF FF)
=> Write to Sector Trailer 00 11 22 33 44 55 FF 0F 00 FF FF FF FF FF FF FF
I found a good tool JSmartCard Explorer which allows you to send APDUs to cards. Then I read PCSC specifications 3.2.2.1.4 Load Keys Command chapter and understood that the command should probably look like this:
FF 82 00 00 18 00 11 22 33 44 55 FF 0F 00 FF FF FF FF FF FF FF
But unfortunately JSmartCard tool fails with "Command not allowed (no current EF)".
What I am doing wrong? How can I change the key?
First of all, MIFARE Classic cards do not use APDU commands. Hence, you do not send APDUs to the card but to the card reader (which translates them into MIFARE Classic commands). APDU commands to be processed by the reader typically start with the class byte FF.
In MIFARE Classic cards, the keys (A and B) and the access conditions for each sector are stored in the sector trailer (the last block of each sector). A MIFARE Classic 1K card has 16 sectors with 4 blocks each.
So if you want to set the keys & access conditions for sector 0, you would need to write them to block 3 (the last block of sector 0). The PC/SC standard defines the write command (UPDATE BINARY) for storage cards as:
FF D6 XXYY 10 ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
Where XXYY is the block address and ZZ... is the data to be written to the block.
The format of the sector trailer is (see this answer for further details):
<key A> | access bits | general purpose byte | <key B>
So in order to set
key A = 00 11 22 33 44 55
key B = 66 77 88 99 AA BB
access bits = 787788 (sector trailer is writable using key B only; access bits/GPB can be read with key A or B; data blocks are writable using key B only; data blocks can be read with key A or B)
GPB is set to 69
for sector 0, you would use the following write command:
FF D6 0003 10 001122334455 787788 69 66778899AABB
Note that you cannot partially update the sector trailer, you always have to construct and write the whole sector trailer.

COBOL capture arrow keystrokes

I'm completely new to COBOL, so as a learning excercise (and just for the sake of it) I'm trying to make a small console based game of connect 4. However I'm struggling to find a way of listening for and reading in keystrokes (for example using the arrow keys to move a piece left and right) without having to press enter after. So far the best solution I've found is to use Microfocus' Enhanced Accept/Display (Adis) which allows the use of the function keys in the manner I would like. I was wondering if there was something I may have missed, or a way of using Adis that would permit me the same sort of functionality with other keys than the function keys. The following program (shamelessly copied from https://www.microfocus.co.jp/manuals/SE/books/uisckb.htm) demonstrates the use of the function keys in the manner I would like:
1$set noosvs mf ans85
2**********************************************************
3* Copyright Micro Focus International 2000. All Rights *
4* Reserved. This demonstration program is provided for *
5* use by users of Micro Focus products and may be used, *
6* modified and distributed as part of your application *
8* provided that you properly acknowledge the copyright *
9* of Micro Focus in this material. *
9**********************************************************
10
11**********************************************************
12* *
13* FUNKEY.CBL *
14* *
15* This program demonstrates how to decode function *
16* keys using the x"af" call. *
17* *
18**********************************************************
19 special-names.
20 crt status is key-status.
21
22 working-storage section.
23 01 flag pic 9(2) comp-x value 1.
24 01 user-key-control.
25 05 enable-fn-keys pic 9(2) comp-x value 1.
26 05 filler pic x value "1".
27 05 first-user-key pic 9(2) comp-x value 1.
28 05 number-of-keys pic 9(2) comp-x value 10.
29
30 01 key-status.
31 05 key-type pic x.
32 05 key-code-1 pic 9(2) comp-x.
33 05 filler pic x.
34 01 any-data pic x.
35 01 key-code-1-display pic z9.
36
37 procedure division.
38 perform enable-keys
39 perform accept-function-key
40 perform tell-which-key-was-pressed
41 perform stop-run.
42
43 enable-keys.
44 call x"af" using flag user-key-control.
45
46 accept-function-key.
47 display spaces upon crt
48 display "Press a function key: F1 to F10" at 0505
49 accept any-data at 0540.
50
51 tell-which-key-was-pressed.
52 evaluate key-type
53 when 0 display "You pressed <Enter>" at 0705
54 when 1
55 move key-code-1 to key-code-1-display
56 display "You pressed function key" at 0705
57 display key-code-1-display at 0730
58 end-evaluate.
59
60 stop-run.
61 stop run.
It you are up for using a little non-conventional COBOL, the S-Lang library is the bee's knees when it comes to keyboard handling. No ADIS required, but with care the two can live peacefully together. Trying this example will require GNU Cobol 1.1 and libslang (by John E. Davis, jedsoft).
OCOBOL >>SOURCE FORMAT IS FIXED
*> ***************************************************************
*> Date: 20090503
*> License: Copyright 2009, Brian Tiffin
*> licensed for use under the GNU GPLv2
*> Purpose: Experimental S-Lang keyboard interface
*> Tectonics: cobc -x slangkey.cob -lslang
*> ***************************************************************
identification division.
program-id. slangkey.
data division.
working-storage section.
01 thekey usage binary-long unsigned.
01 thekm usage binary-long.
01 result usage binary-long.
*> exit handler address and priority (prio is IGNORED with OC1.1)
01 install-flag pic 9 comp-x value 0.
01 install-params.
02 exit-addr usage is procedure-pointer.
02 handler-prio pic 999 comp-x.
*> ***************************************************************
procedure division.
*> Initialize low and high level S-Lang terminal routines
call "SLtt_get_terminfo" end-call
call "SLkp_init" returning result end-call
if result equal -1
display "problem intializing S-Lang tty" end-display
stop run giving 1
end-if
call "SLang_init_tty" using
by value -1 *> abort char
by value -1 *> flow ctrl
by value 0 *> output processing
returning result
end-call
if result equal -1
display "problem intializing S-Lang tty" end-display
stop run giving 1
else
display "Keyboard in special mode" x"0d" end-display
end-if
*> install an exit handler to put terminal back
set exit-addr to entry "tty-reset"
call "CBL_EXIT_PROC" using
install-flag
install-params
returning result
end-call
if result not equal zero
display "error installing exit procedure" end-display
end-if
*> Not sure? Have SLang handle ^C or let GNU Cobol take over?
call "SLang_set_abort_signal" using by value 0 end-call
*> The demo. Fetch a key, then fetch a keycode. 4 times.
*> SLang terminals display newline as newline. Need explicit
*> CR to get a carriage return. Hence the x"0d".
*> Plus, output is buffered until line terminators.
display
"Tap a normal key, then tap a 'special' key, ie F1, 4 times"
x"0d"
end-display
perform 4 times
call "SLang_getkey" returning thekey end-call
display thekey space with no advancing end-display
call "SLkp_getkey" returning thekm end-call
display thekm x"0d" end-display
end-perform
*> Exit handler will take care of resetting terminal
goback.
*> ***************************************************************
*> Exit procedure to ensure terminal properly reset
*> ***************************************************************
entry "tty-reset".
call "SLang_reset_tty" end-call
display "exit proc reset the tty" end-display
goback.
end program slangkey.
A bit late to the party but:
Documentation for ADIS can be found at https://supportline.microfocus.com/Documentation/books/sx51/sx51indx.htm - look for "Character user interfaces", and specifically the section "Keyboard handling via ADIS". The paragraph "enable-function-keys" in your code enables the function keys from F1 to F10. What you need to do is change the function of the cursor keys, which are ADIS keys, and to do this you need
01 adis-key-control.
05 enable-adis-keys pic 9(2) comp-x value 1.
05 filler pic x value "2".
05 first-adis-key pic 9(2) comp-x value 3.
05 number-of-adis-keys pic 9(2) comp-x value 8.
Then add the line
call x"af" using flag adis-key-control.
to the paragraph enable-function-keys. This will allow you to capture cursor left, right, up, and down, plus Home, tab, backtab, and End.
I do not have Micro Focus COBOL, but a quick internet search seems to indicate that the example you chose introduces some confusion by using the term function-keys and show values received from pressing function-keys.
It may be that using the function-keys was the simplest for the example, because the key-value is 1 to 10, so needing no translation from key-value to key that you understand. It shows 3, you know it means F3.
The only clue in the example you show is 05 number-of-keys pic 9(2) comp-x val. If the number of keys used by the x'af' CALL is configurable, then it can changed, then, likely, keys themselves can be changed.
You ask about ADIS (Micro Focus's Extended ACCEPT and DISPLAY)? Yes. It is all within ADIS. All the cursor keys are part of the Standard Adis Key Functions.
If you run the example program and press the arrow keys instead of a function key, what happens?
I searched for micro focus user interface manual and found enough information to make it necessary to know which particular Micro Focus product you have.